题解 深搜 POJ 3009
题意:溜石游戏。在一给定大小的矩形冰面上,散布若干石块,给定石头的初始位置和终点,求从起点到达终点的最小步数,超过10次则视作不可达。其中规则如下,若石头与石块有相邻则不能向该方向滑动;每次溜石只能到达有石块的地方,且将其立即敲碎;若出界则视作失败。
思路:1.建立两个数组作为方向数组。
2.在深搜函数中用循环来对方向进行改变。函数共有三个变量,分别是位置x,y和 移动到该点时所用步数。
3.求最小步数,则在每次得打步数时用min函数和当前步数进行对比。
代码:
#include <iostream>
#include <cstring>
using namespace std;
int n,m,dot[25][25],ans;
int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
bool inbound(int x,int y)
{
if(x>=0&&x<n&&y>=0&&y<m)
return true;
else
return false;
}
void dfs(int x,int y,int step)
{
int i, tx, ty;
if(step>10)
return ;
for(i=0;i<4;i++)
{
if(dot[x+dx[i]][y+dy[i]]==1)
continue;
tx=x,ty=y;
while(1)
{
tx+=dx[i];
ty+=dy[i];
if(!inbound(tx,ty))
break;
else if(dot[tx][ty]==3)
{ans=min(step,ans);return ;}
else if(dot[tx][ty]==1)
break;
}
if(!inbound(tx,ty))
continue;
dot[tx][ty]=0;
dfs(tx-dx[i],ty-dy[i],step+1);
dot[tx][ty]=1;
}
}
int main()
{
int i,j,sx,sy;
while(cin>>m>>n)
{
if(m==0&&n==0)
break;
ans=11;
memset(dot,0,sizeof(dot));
for(i=0;i<n;i++)
for(j=0;j<m;j++)
{
cin>>dot[i][j];
if(dot[i][j]==2)
sx=i,sy=j,dot[i][j]=0;
}
dfs(sx,sy,1);
if(ans>10)
cout<<-1<<endl;
else
cout<<ans<<endl;
}
return 0;
}
错误原因:1.思路混乱,导致编译时间过长,BUG过多。
2.限制条件不清晰,界内判定错误。
3.代码不简洁,易出错。
浙公网安备 33010602011771号