hdu_1010_Tempter of the Bone_dfs

题意:给出一个地图,起点和终点,四通路(上下左右),问在一定的时间内可以走出这个地图吗

题解:首先这个题意一定要好好读,很容易读错题,理解成最短路径小于给定时间就可以出去,其实是不可以的,必须要在给定的时间恰好到达终点才可以走出地图。

         所以不可以用bfs,这里采用dfs的方法,暴力的dfs肯定会超时,因为要枚举每一条道路,所以我们介绍一种剪枝的思路——奇偶剪纸

         还要考虑两个剪枝,就是当能走的步数小于给定的时间肯定不能出去和如果搜索到的步数已经大于给定时间了就不再搜索。

奇偶剪枝:

       奇偶剪纸的含义通俗的我的理解是一个地图,以黑白间隔涂色,白色格子可以一步到达的格子为黑色,黑色格子一步可以到达的格子为白色

       那么很容易得出,从黑色格子走到另一个黑色格子肯定是经过了偶数步,对于这个题来说,我们知道从某一个位置(x1,y1)->(x2,y2)的时候

       所需要的步数一定和(x2-x1)+(y2-y1)这种走法的奇偶性相同。

注意:

       这个题输入竟然有坑,好像有非法输入案例,因为一定要把getchar()写在每行读入的最后面,或者是每次读入一个字符串的形式读一行才不会出错。------这里至今不是很明白为啥,,,因为这个读入wa了n次

代码:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cmath>
 5 using namespace std;
 6 int n,m,t;
 7 int sx,sy;
 8 int dx,dy;
 9 int go[4][2] = {{0,-1},{0,1},{1,0},{-1,0}};
10 int vis[10][10];
11 char mp[10][10];
12 bool in(int x, int y)
13 {
14     if(x<n&&x>=0&&y>=0&&y<m&&vis[x][y]==0) return true;
15     return false;
16 }
17 bool dfs(int x, int y, int time)
18 {
19     if(x==dx&&y==dy&&time==t){
20         return true;
21     }
22     if(time>=t) return false;
23     if(((t-time)%2)!=((abs(x-dx)+abs(y-dy))%2)) return false;
24     if((t-time-abs(x-dx)-abs(y-dy))<0) return false;
25     int tx,ty;
26     for(int i = 0; i < 4; i++){
27         tx = x+go[i][0];
28         ty = y+go[i][1];
29         if(in(tx,ty)){
30             vis[tx][ty] = 1;
31             if(dfs(tx,ty,time+1)) return true;
32             vis[tx][ty] = 0;
33         }
34     }
35     return false;
36 }
37 int main()
38 {
39     int num;
40     while(~scanf("%d%d%d",&n,&m,&t))
41     {
42         num = 0;
43         if(n==0&&m==0&&t==0) return 0;
44         getchar();
45         for(int i = 0; i < n; i++)
46         {
47             for(int j = 0; j < m; j++){
48                 scanf("%c",&mp[i][j]);
49                 if(mp[i][j]=='S'){sx = i; sy = j;vis[i][j] = 1;}
50                 else if(mp[i][j]=='D'){dx = i; dy = j;vis[i][j] = 0;}
51                 else if(mp[i][j]=='X'){vis[i][j] = 1;num++; }
52                 else vis[i][j] = 0;
53             }
54             getchar();
55         }
56         if(n*m-num-1<t)printf("NO
");
57         else if(dfs(sx,sy,0)) printf("YES
");
58         else printf("NO
");
59     }
60     return 0;
61 }
原文地址:https://www.cnblogs.com/shanyr/p/6640569.html