Tempter of the Bone(诱惑的骨头)

hdoj 1010

题目大意:给一个地图,在规定时间内刚好找到出口,不早也不能晚

解决:dfs+剪枝

#include <iostream>

#include <cstdio>

#include <cmath>

using namespace std;

#define s scanf

#define p printf

#define d "%d"

char map[8][8];

int n,m,step;

bool escape;

int sx,sy,ex,ey;

int dx[]={1,-1,0,0};

int dy[]={0,0,1,-1};



void dfs(int x,int y,int current_step)

{   



    if(escape)return ;

    int cnt=abs(x-ex)+abs(y-ey);   //至少需要的步子数

    if(current_step+cnt>step)return; //若到达终点的最小步子数也比要求的步子数大 ,肯定不行了,死定了

    if((step-current_step)%2 != cnt%2)return;//奇偶性剪枝

    for(int i=0;i<4;i++)

    {  

       int nxtx=x+dx[i];

       int nxty=y+dy[i];

       if(nxtx<m && nxtx>=0 && nxty<n && nxty>=0)

       { 

           if(map[nxtx][nxty]=='D' && current_step+1==step){escape=true;return ;}

           if(map[nxtx][nxty]=='.')

           {

                map[nxtx][nxty]='X';

                dfs(nxtx,nxty,current_step+1);

                map[nxtx][nxty]='.';   

           }

       } 

    }

}

int main()

{

    while(s(d d d,&m,&n,&step),m||n||step)

    {

       escape=false;

      int i,j;

    //事实证明,先创建好地图,在一个一个找,比输入一个找一个要快一些

       for(i=0;i<m;i++)

            s("%s",map[i]);



        for(i=0;i<m;i++)

          for(j=0;j<n;j++)

           if(map[i][j]=='S'){sx=i; sy=j; }    

           else if(map[i][j]=='D'){ex=i;ey=j;}  

        dfs(sx,sy,0);

        if(escape)puts("YES");

        else puts("NO");

    }

   system("pause");

    return 0;

}

以上为void 型dfs,一下为有返回值dfs

#include <iostream>

#include <cstdio>

#include <cmath>

using namespace std;

#define s scanf

#define d "%d"

char map[8][8];

int n,m,step;

int sx,sy,ex,ey;

int dx[]={1,-1,0,0};

int dy[]={0,0,1,-1};



bool dfs(int x,int y,int current_step)

{   

    int cnt=abs(x-ex)+abs(y-ey);

    if(current_step+cnt>step)return false;

    if(abs(step-current_step)%2 != cnt%2)return false;

    for(int i=0;i<4;i++)

    {  

       int nxtx=x+dx[i];

       int nxty=y+dy[i];

       if(nxtx<m && nxtx>=0 && nxty<n && nxty>=0)

       { //若从x,y能扩展出新的点,只要这个点在map中,有两种可能

      //第一种是为'D',而且满足结束条件,就返回true就行了,第二种是

     //有路可走,map[nxtx][nxty]='.',再尝试下一步



           if(map[nxtx][nxty]=='D' && current_step+1==step)return true;

           if(map[nxtx][nxty]=='.')

           {

                map[nxtx][nxty]='X';

                //一下这个如果不返回的话,就要超时了如果写成

              //return dfs(nxtx,nxty,current_steo+1);就错了

             //因为这句话是说若下一个为真返回真,下一个为假,返回假,但是实际上

             //只能返回真的情况,为假的话,我们还有for循环可以尝试下一个为真不是

                if(dfs(nxtx,nxty,current_step+1))return true;

                map[nxtx][nxty]='.';   

           }

       } 

    }

    return false;

}

int main()

{

    while(s(d d d,&m,&n,&step),m||n||step)

    {

        

      int i,j;

       for(i=0;i<m;i++)

       {  //这个地方要用scanf,不能用gets,因为这个gets,错了无数次

             s("%s",map[i]);

             for(j=0;j<n;j++)

             if(map[i][j]=='S'){sx=i; sy=j; }    

             else if(map[i][j]=='D'){ex=i;ey=j;}  

      }

      if(dfs(sx,sy,0))puts("YES");

      else puts("NO");

    }

   system("pause");

    return 0;

}

 

你可能感兴趣的:(one)