HDU 1010 Tempter of the Bone 经典深搜~DFS

杭电1010题经典的深搜问题 值得一看~~
解释
一.奇偶剪枝
例如 4*4的矩阵
1 0 1 0
0 1 0 1
1 0 10
0 1 0 1
由1到1 由0到0必走偶数步
由1到0 由0到1必走偶数步
所以 根据这个和时间来判断是否成立
例如 
4 4 5
S . X .  
. . X .
. . X .
D . . . 
代码:
    int dis=abs(bx-ex)+abs(by-ey); 
    if((dis+t)%2!=0){printf("NO\n");continue;}  //奇偶剪枝  
S处于1的位置 D处于0的位置 则必须经历奇数的步骤才可以到达 3,5,7,都可以 到达
如果给的时间是4,6一定不行
二:位置剪枝
nx>=0&&nx<n&&ny>=0&&ny<m
即所给的查找位置不能超过地图的范围
三:
dis>t-time
剩余的时间到达不了既定的位置;

4 4 3
 .S X .  
. . X .
. . X .
 .D . . 
就会排除向左走的情况
如果想左走
dis=4 t=3 time由0变成了1 会减掉这种情况。
四 切记切记要对 代码中我用红线标注的注意 一定要重新进行初始化
如果不重新初始化 还用x,y的话会对其产生影响 是带入子函数的值变化。
正确代码:
post code:

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
int n,m,t,bx,by,ex,ey,flag=0;;
char map[10][10];
int visit[10][10];
int dx[4]={-1,0,0,1},dy[4]={0,-1,1,0}; 
void dfs(int x,int y,int time)
{  
    int i;
    if(flag==1){return;}  //查找成功后返回 
    if(time==t){if(x==ex&&y==ey){flag=1;return;}} //在给定的时间时找到出口 
    if(t<=time){return;} //超出时间未找到 放弃 
    int dis;
    dis=abs(ex-x)+abs(ey-y); //查找的位置 与终点的距离 
    if((dis>t-time)||(dis+t-time)%2!=0)
   //1是剩余的时间到不了既定位置 2是运动中奇偶 剪枝 
    {return;}      //上一句话是关键的剪枝 
    for(i=0;i<4;i++)
    { int nx=x+dx[i];  //切记一定要重新定义查找的地点 keykeykey
      int ny=y+dy[i];
      
      if(nx>=0&&nx<n&&ny>=0&&ny<m&&visit[nx][ny]!=1&&map[nx][ny]!='X')
      {
       //前四个 位置剪枝 第五个 不走返回路 第六个 不走障碍路 
        visit[nx][ny]=1;     //标记已经过 
        dfs(nx,ny,time+1);   //注意营卫time+1 time++是错误的 
        visit[nx][ny]=0;     //将经过 回溯为 未经过                                   
      }                
    }
}

int main()
{  int i,j,temp,dis,ji;
  while(scanf("%d %d %d",&n,&m,&t))
  {
   ji=1;
    for(i=0;i<10;i++)  //对visit数组进行初始化 
     for(j=0;j<10;j++)
        visit[i][j]=0;              
                  
    if(n==0&&m==0&&t==0)break;
               
          for(i=0;i<n;i++)
          {
           scanf("%s",map[i]);
             for(j=0;j<m;j++)
             {
               if(map[i][j]=='S'){bx=i;by=j;} //找到入口位置 
               if(map[i][j]=='D'){ex=i;ey=j;} //找到出口的位置 
               if(map[i][j]=='.'){ji++;}      //记录可行路的个数            
             }
          
          }
    if(ji<t){printf("NO\n");continue;} //可行路的个数小于时间 不行  
    int dis=abs(bx-ex)+abs(by-ey); 
    if((dis+t)%2!=0){printf("NO\n");continue;}  //奇偶剪枝  
    flag=0;
    visit[bx][by]=1; 
    dfs(bx,by,0);
    if(flag==1)printf("YES\n"); //正确找到结果 
    else printf("NO\n");        //为找到结果 
  }
}

下附自己的测试样例

4 4 5
S.X.
..X.
..XD
....
NO

3 4 5
S.X.
..X.
...D
YES

3 4 10
S...
..X.
..D.
YES

3 4 6
....
..X.
.SXD
YES

对四的解释

样例

post  code:

#include<stdio.h>
#include<stdlib.h>
void fun(int t)
{
  printf("t=%d\n",t);
  int i,nt;
  if(t==2)return;
  for(i=1;i<=3;i++)
  { int nt=t+1;
    fun(nt);     
  }   
}

int main()
{
    fun(0);    
    system("pause");
} 
如果我想要的结果是这个:
HDU 1010 Tempter of the Bone 经典深搜~DFS_第1张图片


#include<stdio.h>
#include<stdlib.h>
void fun(int t)
{
  printf("t=%d\n",t);
  int i;
  if(t==2)return;
  for(i=1;i<=3;i++)
  { 
    fun(t++);     //这里会逐渐改变t的值,因为他包含两步份 加一和赋值不会得到上面想要的结果  
                  //若改成t+1和上面的结果一样
  }   
}

int main()
{
    fun(0);    
    system("pause");
} 

你可能感兴趣的:(HDU 1010 Tempter of the Bone 经典深搜~DFS)