就是推箱子,之前也没玩过,导致理解错题意了,应该是把当前格子箱子挪走了一个,剩余的向前推一格,如果前面原来就有箱子,两堆混为一堆,而且不可以把箱子推出网格边界~~
/************ hdu2821 2015.12.2 31MS 1428K 1635 B ************/ #include<cstdio> #include<cstring> #include<cctype> int n,m,num,cnt,a[35][35],dir[4][2]={0,-1,0,1,-1,0,1,0}; char map[35][35],p[]="LRUD",path[625]; int ok(int x,int y) { if(x<0||y<0||x>=n||y>=m) return 0; if(a[x][y]==0) return 1; return -1; } int dfs(int x,int y,int pos) { int i,xx,yy,tx,ty; for(i=0;i<4;i++) { xx=x+dir[i][0]; yy=y+dir[i][1]; if(ok(xx,yy)!=1) continue; do { xx+=dir[i][0]; yy+=dir[i][1]; }while(ok(xx,yy)==1); if(ok(xx,yy)&&ok(tx=xx+dir[i][0],ty=yy+dir[i][1])&&a[xx][yy])//ok(xx,yy)==-1 ok(下一次)=未出界 当前非空 { int t=a[xx][yy]; path[pos]=p[i]; if(t==1||a[tx][ty])//挪走一个就没有了或者要挪到的地方原来就有,两堆混为一堆 { cnt--;//堆数减少 } if(cnt==0) { num=pos; return 1; } a[xx][yy]=0; a[tx][ty]+=t-1; if(dfs(xx,yy,pos+1)) { return 1; } a[xx][yy]=t; a[tx][ty]-=t-1;//回溯 if(t==1||a[tx][ty]) { cnt++; } } } return 0; } int main() { //freopen("cin.txt","r",stdin); while(~scanf("%d%d",&m,&n)) { int i,j,k,x,y,flag=1,f[35][35]={0}; for(i=num=0;i<n;i++) { scanf("%s",map[i]); for(j=0;j<m;j++) if(isalpha(map[i][j])) num++,a[i][j]=map[i][j]-'a'+1; else a[i][j]=0; } for(i=0;i<n&&flag;i++) for(j=0;j<m&&flag;j++) if(a[i][j]) for(k=0;k<4&&flag;k++) { x=i+dir[k][0]*2; y=j+dir[k][1]*2; if(ok(x,y)>0&&!f[x][y]) { f[x][y]=1; cnt=num; if(dfs(x,y,0)) flag=0; } } printf("%d\n%d\n",x,y); for(i=0;i<=num;i++) printf("%c",path[i]); puts(""); } }