这道题的大概意思就是 一个石头 从起始位置出发 每抛一次算走一步 ,石头只能沿格子的直线滑动 直到遇到一个冰块才停下 当它在冰块面前停下后 这个冰块会消失 求最少需要抛几次 可以让冰块到达终点
1.起始位置在以后的抛石头过程中也可以滑动 相当于图中的标记为0的位置
2.题中说跑的次数大于10次了就算做游戏失败 这里相当于给搜索做了一个剪枝
3.因为石头每抛一次遇到一块冰块这个冰块就会消失 相当于要一条路走到黑 当前面的路走不下去了返回的时候 原来路上消失的冰块要重新出现 所以 本题我认为还是用深搜做比较好
这道题我做了很长时间 第一开始没考虑全面 用了广搜 导致结果都不对 后来发现了问题 改用了深搜 又因为自己想的过于复杂 不知道哪一步出错了 导致了超时 还有wrong answer 最后还是上网搜了别人的代码来看 有的人的代码很简单 我表示 敬佩啊 并且为自己的智商低感到羞愧
在此推荐 http://www.cnblogs.com/gj-Acit/archive/2013/04/10/3013165.html http://blog.csdn.net/lyy289065406/article/details/6647671
#include <stdio.h>
#include <string.h>
int ex,ey,sx,sy;
int w,h;
int step,min;
int map[25][25];
int vir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
int judge(int x,int y)
{
if(x>0&&x<=h&&y>0&&y<=w&&map[x][y]!=1)
return 1;
else
{
return 0;
}
}
void dfs(int x,int y)
{
int i;
if(step>10)
return ;//据说这是剪枝 题中说大于10歩 算作游戏失败
for(i=0;i<4;i++)
{
int nx,ny;
int ok=0;
nx=x+vir[i][0];
ny=y+vir[i][1];
while(judge(nx,ny))
{
ok=1;
if(nx==ex&&ny==ey)
{
if(step<min)
{
min=step;
return ;
}
}
nx=nx+vir[i][0];
ny=ny+vir[i][1];
}
if(map[nx][ny]==1&&ok)
{
map[nx][ny]=0;step++;
dfs(nx-vir[i][0],ny-vir[i][1]);
map[nx][ny]=1;step--;
}
}
}
int main()
{
while(~scanf("%d%d",&w,&h)&&w&&h)//w为列 h为宽
{
memset(map,-1,sizeof(map)); //有边界控制 可以不每次都初始化
for(int i=1;i<=h;i++)
{
for(int j=1;j<=w;j++)
{
scanf("%d",&map[i][j]);
if(map[i][j]==2)
{
sx=i;
sy=j;
}
if(map[i][j]==3)
{
ex=i;
ey=j;
}
}
}
min=1000000;
step=1;//记得步子初始化为1 可以仔细想想是为什么 跟着题中的例子走一次即可
dfs(sx,sy);
if(min>10)
{
printf("-1\n");
}
else
{
printf("%d\n",min);
}
}
return 0;
}