hdu 2821 深搜
题意:游戏 http://www.hacker.org/push
棋盘上有几个箱子,可以找个空地,放置'推子'。然后横向或竖向推动,直到遇到箱子,将箱子数减1,推到下一格,若下一格也有箱子,则两者相加。 推子在第一个箱子的原位置。
推子和箱子之间至少有一个空格才能撞动箱子。
分析:深搜。找到任意一种解决方案即可。 注意: 一开始放推子的时候,只能放在空地上。 这点没注意到卡了N小时。
char c[30][30]; int a[30][30]; int n,m,count,flag; int dir[2][4]={{ -1, 1, 0, 0 }, { 0, 0,-1, 1 }}; char dd[]={'U','D','L','R'}; char d[10000]; bool can(int x,int y){ if(x>=0&&x<n&&y>=0&&y<m)return true; return false; } void Readdata(){ count=0; flag=0; for(int i=0;i<n;i++){ cin>>c[i]; for(int j=0;j<m;j++){ if(c[i][j]=='.')a[i][j]=0; else { a[i][j]=(c[i][j]-'a')+1; count+=a[i][j]; } } } } void dfs(int i,int j,int cnt){ if(cnt>=count){flag=1;d[cnt]='\0';return;} for(int k=0;k<4;k++){ if(flag)return; int x=i+dir[0][k],y=j+dir[1][k]; if( !can(x,y) || a[x][y] ) continue; while( can(x,y) &&!a[x][y] ) { x+=dir[0][k]; y+=dir[1][k]; } if(!can(x,y)) continue; d[cnt]=dd[k]; int u=a[x][y]; if(u>1&&!can(x+dir[0][k],y+dir[1][k]))continue; if(u>1) a[x+dir[0][k]][y+dir[1][k]]+=u-1; a[x][y]=0; dfs(x,y,cnt+1); if(flag)return; if(u>1) a[x+dir[0][k]][y+dir[1][k]]-=u-1; a[x][y]=u; } } int ax,ay; void solve(){ for(int i=0;i<n;i++) for(int j=0;j<m;j++){ if(a[i][j])continue; //for(int k=0;k<4;k++){ if(flag)return; //int x=i+dir[0][k], y=j+dir[1][k],xx=x+dir[0][k],yy=y+dir[1][k]; //if(can(xx,yy)&&a[xx][yy]&&!a[x][y]) { ax=i; ay=j; dfs(i,j,0); //} //} } } int main(){ while(cin>>m>>n){ Readdata(); solve(); if(flag){ cout<<ax<<endl<<ay<<endl; int i=0; while(d[i]!='\0')cout<<d[i++]; cout<<endl; } } return 0; }