题目链接:http://poj.org/problem?id=3009
题意:就是要求把一个冰壶从起点“2”用最少的步数移动到终点“3”。其中0为移动区域,1为石头区域,冰壶一旦想着某个方向运动就不会停止,也不会改变方向(想想冰壶在冰上滑动),除非冰壶撞到石头1 或者 到达终点 3。
注意的是:冰壶撞到石头后,冰壶会停在石头前面,此时(静止状态)才允许改变冰壶的运动方向,而该块石头会破裂,石头所在的区域由1变为0. 也就是说,冰壶撞到石头后,并不会取代石头的位置。终点是一个摩擦力很大的区域,冰壶若到达终点3,就会停止在终点的位置不再移动。
解题思路:该题的话也是一道深度优先搜索的题目,但是题目中的限制条件特别多,题意也不好理解。刚开始没看清题意WA了好多次。
#include <cstdio>
#include <iostream>
#include <memory.h>
using namespace std;
const int maxn=30;
int ans=9999;
int w,h;
int dir[4][2]={{-1,0},{0,1},{0,-1},{1,0}};
int Map[maxn][maxn];
void dfs(int l,int o,int step)
{
int x,y;
if(step>ans||step>10)
return;
for(int i=0;i<4;i++)
{
x=l;
y=o;
if(Map[x+dir[i][0]][y+dir[i][1]]!=1)
{
while(Map[x+dir[i][0]][y+dir[i][1]]!=1)
{
x=x+dir[i][0];
y=y+dir[i][1];
if(!(x>=1&&x<=h&&y>=1&&y<=w))
break;
if(Map[x][y]==3)
{
if(step+1<ans)
{
ans=step+1;
}
return;
}
}
if(x>=1&&x<=h&&y>=1&&y<=w)
{
Map[x+dir[i][0]][y+dir[i][1]]=0;
dfs(x,y,step+1);
Map[x+dir[i][0]][y+dir[i][1]]=1;
}
}
}
}
int main()
{
while(scanf("%d %d",&w,&h)&&w&&h)
{
int x,y;
int step=0;
memset(Map, 0, sizeof(Map));
for(int i=1;i<=h;i++)
for(int j=1;j<=w;j++)
{
cin>>Map[i][j];
if(Map[i][j]==2)
{
x=i;
y=j;
}
}
dfs(x,y,step);
if(ans>10)
cout<<"-1"<<endl;
else
cout<<ans<<endl;
ans=9999;
}
return 0;
}