题解 深搜 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.代码不简洁,易出错。