Pusher
TimeLimit: 2000/1000 MS (Java/Others) Memory Limit: 32768/65536 K (Java/Others)
Total Submission(s): 169Accepted Submission(s): 67
SpecialJudge
ProblemDescription
PusherBoy is an online gamehttp://www.hacker.org/push . There is an R * C grid, and there are piles ofblocks 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. Thenyou can choose which direction (U for up, D for down, L for left and R forright) to push. Once the direction is chosen, the PusherBoy will walk aheaduntil he met a pile of blocks (Walking outside the grid is invalid). Then heremove one block from the pile (so if the pile contains only one block, it willbecome empty), and push the remaining pile of blocks to the next area. (Ifthere have been some blocks in the next area, the two piles will form a new bigpile.)
Please note if the pusher is right up against the block, he can't remove andpush it. That is, there must be a gap between the pusher and the pile. As thefollowing figure, the pusher can go up, but cannot go down. (The cycleindicates the pusher, and the squares indicate the blocks. The nested squaresindicate a pile of two blocks.)
And if a whole pile is pushed outside the grid, it will be considered ascleared.
Input
There are several test cases in each input.The first two lines of each case contain two numbers C and R. (R,C <= 25)Then R lines follow, indicating the grid. '.' stands for an empty area, and alowercase letter stands for a pile of blocks. ('a' for one block, 'b' for twoblocks, 'c' for three, and so on.)
Output
Output three lines for each case. The firsttwo lines contains two numbers x and y, indicating the initial position of thePusherBoy. (0 <= x < R, 0 <= y < C). The third line contains amoving sequence contains 'U', 'D', 'L' and 'R'. Any correct answer will beaccepted.
SampleInput
3 7 ... ... .b. ...... .a. ...
SampleOutput
4 1 UDU
Hint
Hint: The following figures showthe sample. The circle is the position of the pusher. And the squares areblocks (The two nested squares indicating a pile of two blocks). And this isthe unique solution for this case.
Source
算法分析:
一开始都每=没看懂题意,重新搜了这个题,有图就好理解多了,但依旧有点模糊,不知道如何消除块,看了一下别人的题解,才弄明白。
就是你找到一个点开始推木块,但点满足与木块之间有空格,才能推动,以后都要按照这个方向推动,且推一次少一个木块但剩下的木块到下一个区域。一直dfs就行了朝着某个方向一直推到边界或者遇到箱子不能推
为止才可以换方向。
代码实现:
#include<bits/stdc++.h>
using namespace std;
int n,m,tot,flag;//tot记录木块数
int a[30][30];
int dx[4]={-1,1,0,0},
dy[4]={0,0,-1,1};
char dir[5]="UDLR";
char mapp[30][30],path[1000];//path记录方向路径
int dfs(int x,int y,int ans)//ans清除了多少木块
{
if(ans==tot) {return 1;}
int x1,y1,i;
for(i=0;i<4;i++)
{
x1=x+dx[i];
y1=y+dy[i];
if((x1<=0||y1<=0||x1>n||y1>m)||a[x1][y1]!=0)//越界 不行,第一个遇到木块不行
continue;
do //方向不能变
{
x1+=dx[i];
y1+=dy[i];
}while(a[x1][y1]==0&&(x1<=n&&x1>0&&y1<=m&&y1>0));//遇到木块出来
if(x1<=n&&x1>0&&y1<=m&&y1>0)
{
int temp=a[x1][y1];
a[x1+dx[i]][y1+dy[i]]+=(temp-1);//减一个,推入下一个区域
path[ans]=dir[i]; //记录路径
a[x1][y1]=0; //当前区域清0
if(dfs(x1,y1,ans+1)) return 1;
a[x1][y1]=temp;
a[x1+dx[i]][y1+dy[i]]-=(temp-1);
}
}
return 0;
}
int main()
{
int i,j,t;
while(scanf("%d%d",&m,&n)!=EOF)
{
tot=0;
memset(a,0,sizeof(a));
memset(mapp,0,sizeof(mapp));
memset(path,0,sizeof(path));
//清0工作
for(i=1;i<=n;i++) //把mapp转化a
for(j=1;j<=m;j++)
{
cin>>mapp[i][j];
if(mapp[i][j]<='z'&&mapp[i][j]>='a')
{
tot+=(mapp[i][j]-'a'+1); //记录方块总数
a[i][j]=mapp[i][j]-'a'+1; //记录每个方块总数
}
else
a[i][j]=0;
}
for(i=1;i<=n;i++)//枚举点
{
for(j=1;j<=m;j++)
if(!a[i][j]&&dfs(i,j,0))
{
cout<<i-1<<endl<<j-1<<endl;
for(t=0;t<tot;t++)
{
cout<<path[t];
}
cout<<endl;
}
}
}
return 0;
}