PusherBoy is an online game http://www.hacker.org/push . There is an R * C grid, and there are piles of blocks on some positions. The goal is to clear the blocks by pushing into them.
You should choose an empty area as the initial position of the PusherBoy. Then you can choose which direction (U for up, D for down, L for left and R for right) to push. Once the direction is chosen, the PusherBoy will walk ahead until he met a pile of blocks (Walking outside the grid is invalid). Then he remove one block from the pile (so if the pile contains only one block, it will become empty), and push the remaining pile of blocks to the next area. (If there have been some blocks in the next area, the two piles will form a new big pile.)
Please note if the pusher is right up against the block, he can't remove and push it. That is, there must be a gap between the pusher and the pile. As the following figure, the pusher can go up, but cannot go down. (The cycle indicates the pusher, and the squares indicate the blocks. The nested squares indicate a pile of two blocks.)
And if a whole pile is pushed outside the grid, it will be considered as cleared.
You should choose an empty area as the initial position of the PusherBoy. Then you can choose which direction (U for up, D for down, L for left and R for right) to push. Once the direction is chosen, the PusherBoy will walk ahead until he met a pile of blocks (Walking outside the grid is invalid). Then he remove one block from the pile (so if the pile contains only one block, it will become empty), and push the remaining pile of blocks to the next area. (If there have been some blocks in the next area, the two piles will form a new big pile.)
Please note if the pusher is right up against the block, he can't remove and push it. That is, there must be a gap between the pusher and the pile. As the following figure, the pusher can go up, but cannot go down. (The cycle indicates the pusher, and the squares indicate the blocks. The nested squares indicate a pile of two blocks.)
And if a whole pile is pushed outside the grid, it will be considered as cleared.
3 7 ... ... .b. ... ... .a. ...
4 1 UDU
Hint: The following figures show the sample. The circle is the position of the pusher. And the squares are blocks (The two nested squares indicating a pile of two blocks). And this is the unique solution for this case.
题意:有一个R*C的方格,‘.’代表空地,‘a~z’分别代表该处有1~26个箱子,某人可以从距离箱子至少一个空格处推箱子,推一次此处
少一个箱子,如果这个格还有其他箱子,则和它下一个格的箱子合并或到下一个格,朝着某个方向一直推到边界或者遇到箱子不能推
为止才可以换方向,任意输出一种可以把箱子推完的方案,输出推箱子时起点的位置以及推箱子时的方向
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int t[4][2]= {-1,0,1,0,0,-1,0,1}; //上下左右 int a[33][33]; char c[33][33]; int path[100]; int sum,num,n,m; int judge(int tx,int ty) { if(tx<0||tx>=n||ty<0||ty>=m) return 0; return 1; } int dfs(int x,int y,int z) { if(z==sum) //把箱子推完了 return 1; for(int i=0; i<4; i++) { int tx=x+t[i][0]; int ty=y+t[i][1]; if(!judge(tx,ty)||a[tx][ty]!=0) //越界 或者人和箱子之间没有空格 continue; while(!a[tx][ty]&&judge(tx,ty)) //朝着某个方向走到不能走为止 { tx+=t[i][0]; ty+=t[i][1]; } if(!judge(tx,ty)) continue; path[z]=i; //记录推得方向 int k=a[tx][ty]-1; a[tx][ty]=0; //推过后此处便没有箱子 a[tx+t[i][0]][ty+t[i][1]]+=k; //下一个格的箱子数增加 if(dfs(tx,ty,z+1)) return 1; else //回溯 { a[tx+t[i][0]][ty+t[i][1]]-=k; a[tx][ty]=k+1; } } return 0; } int main() { while(~scanf("%d%d",&m,&n)) { sum=0; int t=0; memset(path,0,sizeof(path)); for(int i=0; i<n; i++) { scanf("%s",c[i]); for(int j=0; j<m; j++) { if(c[i][j]>='a'&&c[i][j]<='z') { a[i][j]=c[i][j]-'a'+1;//此处有几个箱子 sum+=a[i][j];//算出箱子的总个数 } else a[i][j]=0; } } for(int i=0; i<n; i++) { for(int j=0; j<m; j++) { if(!a[i][j]) { if(dfs(i,j,0)) { printf("%d\n%d\n",i,j); for(int k=0; k<sum; k++) { if(path[k]==0) printf("U"); if(path[k]==1)printf("D"); if(path[k]==2) printf("L"); if(path[k]==3)printf("R"); } printf("\n"); t=1; break; } } } if(t==1) break; } } return 0; }