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

posted on 2014-07-17 14:12  一锅土豆  阅读(107)  评论(0编辑  收藏  举报