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;
}

 

posted on 2011-08-25 15:02  猿类的进化史  阅读(236)  评论(0编辑  收藏  举报