题目链接:http://poj.org/problem?id=3009
题目大意:一块石头在冰面上滑行,冰面上有一些障碍物,只有遇到障碍物的时候才会停止,并且击碎障碍物,击碎之后就可以在上面滑行。如果超出边界,那么游戏结束。当石头贴着障碍物时,石头将不能向障碍物的方向滑行。最后求从出发点到目标点的最小移动次数,超出10次就当做无法完成。
思路:DFS,刚开始没有判出界wa了一次。。。
下面是代码:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int dir[4][2]={1,0,-1,0,0,1,0,-1}; //方向
int w,h;
int map[105][105];
int s[2],g[2];
int DFS(int x,int y,int k)
{
if(!k) return 10; //超过10次就返回
int xc,yc,flag;
int ans=15;
for(int i=0;i<4;i++)
{
flag=0;
xc=x;
yc=y;
while(1)
{
xc+=dir[i][0];
yc+=dir[i][1];
if(xc<=0||xc>h||yc<=0||yc>w)
{
flag=1; //标记是否出界
break;
}
if(map[xc][yc]==1) //当撞到障碍物时停止运动
{
xc-=dir[i][0];
yc-=dir[i][1];
break;
}
if(xc==g[0]&&yc==g[1]) //到达目标位置
return 1;
}
if(flag) continue;
if(xc!=x||yc!=y)
{
map[xc+dir[i][0]][yc+dir[i][1]]=0; //撞碎障碍物
ans=min(ans,DFS(xc,yc,k-1));
map[xc+dir[i][0]][yc+dir[i][1]]=1; //还原障碍物
}
}
return ans+1;
}
int main()
{
while(cin>>w>>h,w&&h)
{
for(int i=1;i<=h;i++)
{
for(int j=1;j<=w;j++)
{
cin>>map[i][j];
if(map[i][j]==2)
s[0]=i,s[1]=j,map[i][j]=0;
if(map[i][j]==3)
g[0]=i,g[1]=j,map[i][j]=0;
}
}
int ans=DFS(s[0],s[1],10);
if(ans>10) ans=-1;
cout<<ans<<endl;
}
}