Codeforces Round #155 (Div. 2)

来源:互联网 发布:playhome捏脸数据 编辑:程序博客网 时间:2024/06/09 22:32

题目:http://www.codeforces.com/contest/254

D:任意找一个R点bfs找到能炸死它的位置,枚举所有位置,对于位置A,再找一个A炸不到的R点,bfs找到能炸死它的所有位置,再枚举位置,对于枚举的位置B,判断一下A,B能不能炸死所有的老鼠。

#include<stdio.h>#include<string.h>#include<stdlib.h>#include<algorithm>#include<vector>#include<queue>#include<math.h>#include<string>#include<map>#include<set>#include<iostream>using namespace std;typedef long long ll;const int inf = 1 << 29;#define N 1010char a[N][N];struct node{int x,y;int step;};int dd[4][2]={{1,0},{0,1},{-1,0},{0,-1}};int n,m;int vis[20][20];vector<pair<int,int> > e[2];set<pair<int,int> > S,ans;void bfs(int si,int sj,int d,int k){node t,tt;queue<node> qu;t.x=si,t.y=sj;t.step=0;memset(vis,0,sizeof(vis));vis[d][d]=1;qu.push(t);while(!qu.empty()){t=qu.front();qu.pop();if (k==1) {if (a[t.x][t.y] != 'X') {e[0].push_back(make_pair(t.x, t.y));}}else if(k==0){if (a[t.x][t.y] == 'R')S.insert(make_pair(t.x, t.y));}else if(k==2){if (a[t.x][t.y] != 'X')e[1].push_back(make_pair(t.x, t.y));}else if (k == 3) {if (a[t.x][t.y] == 'R')ans.insert(make_pair(t.x, t.y));}if(t.step>=d) continue;tt.step=t.step+1;for(int i=0;i<4;i++){tt.x=t.x+dd[i][0];tt.y=t.y+dd[i][1];if(tt.x<0||tt.x>=n||tt.y<0||tt.y>m) continue;if(a[tt.x][tt.y]=='X') continue;if(vis[tt.x-si+d][tt.y-sj+d]) continue;vis[tt.x-si+d][tt.y-sj+d]=1;qu.push(tt);}}}vector<pair<int,int> > R;int main() {//freopen("input.txt","r",stdin);//freopen("output.txt","w",stdout);int d;scanf("%d%d%d",&n,&m,&d);for(int i=0;i<n;i++)scanf("%s",a[i]);for (int i = 0; i < n; i++)for (int j = 0; j < m; j++) {if (a[i][j] == 'R') {R.push_back(make_pair(i,j));}}bfs(R[0].first,R[0].second,d,1);for(int i=0;i<(int)e[0].size();i++){S.clear();bfs(e[0][i].first, e[0][i].second, d,0);e[1].clear();if (S.size() == R.size()) {for (int j = 0; j < n; j++)for (int k = 0; k < m; k++) {if ((j != e[0][i].first || k != e[0][i].second)&& a[j][k] != 'X') {printf("%d %d %d %d\n", e[0][i].first+1, e[0][i].second+1,j+1, k+1);return 0;}}}for(int j=1;j<(int)R.size();j++){if(S.find(R[j])==S.end()){bfs(R[j].first,R[j].second,d,2);break;}}for(int j=0;j<(int)e[1].size();j++){ans.clear();for(set<pair<int,int> >::iterator it=S.begin();it!=S.end();it++)ans.insert(*it);bfs(e[1][j].first, e[1][j].second, d,3);if(ans.size()==R.size()){printf("%d %d %d %d\n",e[0][i].first+1,e[0][i].second+1,e[1][j].first+1, e[1][j].second+1);return 0;}}}printf("-1\n");}


E:dp题,dp[i][j]表示i天过后还剩j数量的食物时的最大值,对于第i天枚举朋友数进行转移,记录路径输出


#include<stdio.h>#include<string.h>#include<stdlib.h>#include<algorithm>#include<vector>#include<queue>#include<math.h>#include<string>#include<map>#include<set>#include<iostream>using namespace std;typedef long long ll;const int inf = 1 << 29;int a[410];vector<pair<int,int> > e[410];int pre[410][410];int op[410][410];int dp[410][410];void output(int i,int n){if(!i) return;output(i-1,pre[i][n]);int k=op[i][n];printf("%d",k);for(int j=0;j<k;j++){printf(" %d",e[i][j].second);}puts("");}int cost[410][410];int main() {//freopen("input.txt","r",stdin);//freopen("output.txt","w",stdout);int n,v,m,l,r,f;scanf("%d%d",&n,&v);for(int i=1;i<=n;i++)scanf("%d",&a[i]);scanf("%d",&m);for(int i=0;i<m;i++){scanf("%d%d%d",&l,&r,&f);for(int j=l;j<=r;j++){e[j].push_back(make_pair(f,i+1));}}for(int i=1;i<=n;i++){sort(e[i].begin(),e[i].end());for(int j=0;j<(int)e[i].size();j++){cost[i][j+1]=cost[i][j]+e[i][j].first;}}memset(dp,-1,sizeof(dp));dp[0][0]=0;for(int i=0;i<n;i++){for(int j=0;j<=a[i];j++){if(dp[i][j]==-1) continue;int t=j+a[i+1];for(int k=0;k<=(int)e[i+1].size();k++){if(cost[i+1][k]+v>t) break;int tt=t-cost[i+1][k]-v;tt=min(tt,a[i+1]);if(dp[i+1][tt]<k+dp[i][j]){dp[i+1][tt]=k+dp[i][j];pre[i+1][tt]=j;op[i+1][tt]=k;}}}}int ans=-1,pos;for(int i=0;i<=a[n];i++){if(ans<dp[n][i]){ans=dp[n][i];pos=i;}}printf("%d\n",ans);output(n,pos);}

原创粉丝点击