Google Codejam 2009 Round 2

来源:互联网 发布:微信相册软件 编辑:程序博客网 时间:2024/05/18 03:42

https://code.google.com/codejam/contest/204113/dashboard#s=p1


小的case是暴搜过的。在一个位置有四种选择,左走,右走,左挖,右挖。

记得刚右走一步之后,不能马上左走,要不死循环了。

一个剪枝是如果当然挖的多余当前最好的解。

#include <iostream>#include <string.h>#include <math.h>#include <queue>#include <set>#include <map>#include <algorithm>#include <stdio.h>#include <string>#include <cctype>#include <ctime>#include <strstream>typedef long long ll;using namespace std;#define N 55int R,C,F,ans;bool ca[N][N];struct sol{int x,y,di,la;//la=-1×ó±ß£¬0ÎÞ£¬1ÓÒ±ßsol(){};sol(int _x,int _y,int _d,int _l){x=_x;y=_y;di=_d;la=_l;}};void se(sol c){int i;if(c.x==R-1){if(c.di<ans){ans=c.di;}return;}if(c.di>=ans)return;if(c.y<C-1){if(c.la!=1&&ca[c.x][c.y+1]==0&&ca[c.x+1][c.y+1])se(sol(c.x,c.y+1,c.di,-1));if(ca[c.x][c.y+1]==0&&ca[c.x+1][c.y+1]==0){i=c.x+2;while(ca[i][c.y+1]==0)i++;if(i-c.x-1<=F)se(sol(i-1,c.y+1,c.di,0));}if(ca[c.x][c.y+1]==0&&ca[c.x+1][c.y+1]){ca[c.x+1][c.y+1]=0;se(sol(c.x,c.y,c.di+1,0));ca[c.x+1][c.y+1]=1;}}if(c.y>0){if(c.la!=-1&&ca[c.x][c.y-1]==0&&ca[c.x+1][c.y-1])se(sol(c.x,c.y-1,c.di,1));if(ca[c.x][c.y-1]==0&&ca[c.x+1][c.y-1]==0){i=c.x+2;while(ca[i][c.y-1]==0)i++;if(i-c.x-1<=F)se(sol(i-1,c.y-1,c.di,0));}if(ca[c.x][c.y-1]==0&&ca[c.x+1][c.y-1]){ca[c.x+1][c.y-1]=0;se(sol(c.x,c.y,c.di+1,0));ca[c.x+1][c.y-1]=1;}}}int main(){ios_base::sync_with_stdio(false);freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);int cas;int ki,i,j;char ch;scanf("%d",&cas);for(ki=1;ki<=cas;ki++){printf("Case #%d: ",ki);//cin>>R>>C>>F;scanf("%d%d%d",&R,&C,&F);for(i=0;i<R;i++){ch=getchar();for(j=0;j<C;j++){ch=getchar();if(ch=='.')ca[i][j]=0;else ca[i][j]=1;}}for(j=0;j<C;j++)ca[R][j]=1;ans=99999;se(sol(0,0,0,0));if(ans==99999)puts("No");else printf("Yes %d\n",ans);fflush(stdout);}return 0;}

大的case是看了解析之后,才做的。看完也想了好久。

我开的是50*50*50*2*2的数组。dp[x][l][r][bl][br]来存储

刚到第x行时,最左可以走到l位置,最右可以走到r位置,bl,br=0表示l或者r处可以落下去,bl,br=1表示l或者r外是墙,l,r处不能落。

发现搜索的顺序,会影响结果:要先搜拆的少的情况,后搜拆的多的。

下面是代码。

#include <iostream>#include <string.h>#include <math.h>#include <queue>#include <set>#include <map>#include <algorithm>#include <stdio.h>#include <string>#include <cctype>#include <ctime>#include <strstream>typedef long long ll;using namespace std;#define N 55#define INF 99999int R,C,F,ans;bool ca[N][N];int dp[N][N][N][2][2];void dis(){int i,j;for(i=0;i<R;i++){for(j=0;j<C;j++)printf("%d ",ca[i][j]);puts("");}}int se(int x,int y,int l,int r,bool bl,bool br)//bl==1×ó±ßÊÇǽ£¬0×ó±ßÊÇ¿Õ{if(x==R-1)return 0;if(l==-2){bl=br=1;for(l=y;l>=0;l--){if(ca[x][l]){break;}if(!ca[x+1][l]){bl=0;break;}}if(bl)l++;for(r=y;r<C;r++){if(ca[x][r]){break;}if(!ca[x+1][r]){br=0;break;}}if(br)r--;}if(dp[x][l][r][bl][br]!=-1)return dp[x][l][r][bl][br];//printf("%d %d %d %d %d %d\n",x,y,l,r,bl,br);if(bl&&br&&l==r)return dp[x][l][r][bl][br]=INF;int i,j,k;set<int> ret;ret.insert(INF);if(!bl){i=x+2;while(ca[i][l]==0)i++;if(i-x-1<=F)ret.insert(se(i-1,l,-2,0,0,0));ret.insert(se(x,y,l+1,r,1,br));for(j=1;l+j<r;j++)if(ca[x+1][l+j+1]){ca[x+1][l+j]=0;i=x+2;while(ca[i][l+j]==0)i++;if(i-x-1<=F)ret.insert(se(i-1,l+j,-2,0,0,0)+j);}for(j=1;l+j<r;j++)ca[x+1][l+j]=1;}else if(ca[x+1][l+1]){ret.insert(se(x,y,l+1,r,1,br));ca[x+1][l]=0;ret.insert(se(x,y,l,r,0,br)+1);ca[x+1][l]=1;}if(!br){i=x+2;while(ca[i][r]==0)i++;if(i-x-1<=F)ret.insert(se(i-1,r,-2,0,0,0));ret.insert(se(x,y,l,r-1,bl,1));for(j=1;r-j>l;j++)if(ca[x+1][r-j-1]){ca[x+1][r-j]=0;i=x+2;while(ca[i][r-j]==0)i++;if(i-x-1<=F)ret.insert(se(i-1,r-j,-2,0,0,0)+j);}for(j=1;r-j>l;j++)ca[x+1][r-j]=1;}else if(ca[x+1][r-1]){ret.insert(se(x,y,l,r-1,bl,br));ca[x+1][r]=0;ret.insert(se(x,y,l,r,bl,0)+1);ca[x+1][r]=1;}//dis();//printf("%d %d %d %d %d\t\t%d\n\n",x,l,r,bl,br,*ret.begin());return dp[x][l][r][bl][br]=*ret.begin();}int main(){ios_base::sync_with_stdio(false);freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);int cas;int ki,i,j;char ch;scanf("%d",&cas);for(ki=1;ki<=cas;ki++){printf("Case #%d: ",ki);//cin>>R>>C>>F;scanf("%d%d%d",&R,&C,&F);memset(dp,-1,sizeof(dp));for(i=0;i<R;i++){ch=getchar();for(j=0;j<C;j++){ch=getchar();if(ch=='.')ca[i][j]=0;else ca[i][j]=1;}}for(j=0;j<C;j++)ca[R][j]=1;ans=se(0,0,-2,0,0,0);if(ans>=INF)puts("No");else printf("Yes %d\n",ans);fflush(stdout);}return 0;}


0 0
原创粉丝点击