题目
题解思路
因为石头击中砖块后,砖块会消失,破坏了地形,所以我们需要回溯处理。
又因为石头能走的路径受到旁边砖块的影响,所以我们不需要标记(也可以标记在次数内),因为题目有行走的次数限制,而且不多,所以我们只需要剪枝,不需要标记。
此题给我的感觉和那题推箱子有点类似,人的位置会影响箱子能推的位置,所以,给箱子能多走一部分重复的路的权限。
AC代码
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int n,m,sx,sy,ex,ey;
int mp[50][50];
int ans = 99999 ;
void dfs(int x,int y,int step)
{
if (step > ans )
return ;
if ( x == ex && y == ey )
{
ans = step;
return ;
}
if (step == 11)
return;
int dx = x;
int dy = y;
if ( mp[x-1][y] != 1)
{
while(dx!=0) //ÍùÉÏ
{
dx--;
if ( dx == ex && y == ey )
{
ans = min(step + 1,ans);
break;
}
if( dx != 0 && mp[dx][y] == 1)
{
mp[dx][y] = 0;
dfs(dx+1,y,step+1);
mp[dx][y] = 1;
break;
}
}
}
dx = x;
if ( mp[x+1][y] != 1)
{
while(dx!=n+1) //ÍùÏÂ
{
dx++;
if ( dx == ex && y == ey )
{
ans = min(step + 1,ans);
break;
}
if(dx != n+1 && mp[dx][y] == 1 )
{
mp[dx][y] = 0;
dfs(dx-1,y,step+1);
mp[dx][y] = 1;
break;
}
}
}
if ( mp[x][y-1] != 1)
{
while(dy!=0) //Íù×ó
{
dy--;
if ( x == ex && dy == ey )
{
ans = min(step + 1,ans);
break;
}
if(dy != 0 && mp[x][dy] == 1 )
{
mp[x][dy] = 0;
dfs(x,dy+1,step+1);
mp[x][dy] = 1;
break;
}
}
}
dy = y;
if ( mp[x][y+1] != 1 )
{
while(dy!=m+1) //ÍùÓÒ
{
dy++;
if ( x == ex && dy == ey )
{
ans = min(step + 1,ans);
break;
}
if(dy != m+1 && mp[x][dy] == 1 )
{
mp[x][dy] = 0;
dfs(x,dy-1,step+1);
mp[x][dy] = 1;
break;
}
}
}
}
int main ()
{
while(~scanf("%d%d",&m,&n))
{
ans = 99999;
if ( m == 0 && n == 0 )
break;
for (int i = 1 ; i <= n ; i++ )
for (int k = 1 ; k <= m ; k++ )
{
scanf("%d",&mp[i][k]);
if ( mp[i][k] == 2 )
{
sx = i;
sy = k;
mp[i][k] = 0;
}
if ( mp[i][k] == 3 )
{
ex = i;
ey = k;
}
}
dfs(sx,sy,0);
if ( ans >10 )
printf("-1\n");
else
printf("%d\n",ans);
}
return 0;
}