题目理解了半天- -
在r*c的网格上面放置有一些箱子,你可以选择任意一块个空地作为你的起点。有上下左右四种移动的操作。一旦选择了一个方向,你会不停地朝这个方向走下去直到的撞到了箱子。被你撞到的箱子会向你行走的方向移动一格,而且数量会减少一个(如果你是紧贴着箱子并且朝它行走,这样的操作是无效的)。如果箱子移动到的位置本来就有箱子,那么他们会合并为新的一堆。
请你寻找任意一个放置人位置和移动的方案,使得所有箱子都能被消除。
很显然有多少个箱子就要走多少步。
于是枚举每一个空位置作为起点,深搜出结果。减枝都不用。
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int n,m,mp[30][30],ans[1010],cnt,sum,sx,sy;
int dir[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};
char str[30][30],op[4] = {'U','D','L','R'};
void init()
{
memset(str,0,sizeof str);
memset(mp,0,sizeof mp);
memset(ans,0,sizeof ans);
cnt = sum = sx = sy = 0;
}
bool inarea(int i,int j)
{
if(i < 1||i > n||j < 1||j > m) return false;
else return true;
}
void dfs(int x,int y,int step)
{
if(step >= sum)
{
cnt = step;
return;
}
for(int i = 0; i < 4; i++)
{
int tx = x+dir[i][0],ty = y+dir[i][1];
if(!inarea(tx,ty) || mp[tx][ty]) continue;
while(inarea(tx,ty)&&!mp[tx][ty])
tx += dir[i][0],ty += dir[i][1];
if(!inarea(tx,ty)||!inarea(tx+dir[i][0],ty+dir[i][1])) continue;
int temp = mp[tx][ty];
ans[step] = i;
mp[tx][ty] = 0,mp[tx+dir[i][0]][ty+dir[i][1]] += temp-1;
dfs(tx,ty,step+1);
if(cnt) return;
ans[step] = 0;
mp[tx][ty] = temp,mp[tx+dir[i][0]][ty+dir[i][1]] -= temp-1;
}
}
int main()
{
while(scanf("%d%d",&m,&n) != EOF)
{
init();
for(int i = 1; i <= n; i++)
{
scanf("%s",str[i]+1);
for(int j = 1; j <= m; j++)
if(str[i][j] >= 'a'&&str[i][j] <= 'z')
{
mp[i][j] = str[i][j]-'a'+1;
sum += mp[i][j];
}
else mp[i][j] = 0;
}
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
if(!mp[i][j])
{
dfs(i,j,0);
sx = i,sy = j;
}
if(cnt) break;
}
if(cnt) break;
}
printf("%d\n%d\n",sx-1,sy-1);
for(int i = 0; i < cnt; i++)
printf("%c",op[ans[i]]);
printf("\n");
}
}