hdu 1010 dfs 走到终点时刚好花掉所有时间 奇偶性剪枝

题意:输入一个n*m的迷宫,和一个T:可以在迷宫中生存的最大时间。S为起点,D为终点。并且,每个格子只能踩一次,且只能维持一秒,然后该块地板就会塌陷。所以你必须每秒走一步,且到D点时,所用时间为T。用深搜。
奇偶性剪枝:如果当前的狗所在的坐标与D的坐标奇偶性不一样,那么狗需要走奇数步。
同理,如果狗所在坐标与D的坐标奇偶性一样,那么狗需要走偶数步数。

也就是说,狗的坐标x、y和对2取余是它的奇偶性,Dxy和对2取余是D的奇偶性。
两个奇偶性一加再对2取余,拿这个余数去与剩下时间对2取余的余数作比较即可。

Sample Input
4 4 5
S.X.
..X.
..XD
....
3 4 5
S.X.
..X.
...D
0 0 0

Sample Output
NO
YES

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <cmath>
 5 #include <vector>
 6 #include <queue>
 7
 8 using namespace std;
 9
10
11 int m,n,t;
12 char map[8][8];
13 int dir[4][2]={{1,0},{-1,0},{0,-1},{0,1}};
14 int ex,ey,sx,sy,ok;//e表示end,终点,s表示start,出发点,ok用来判断是否在规定时间到达
15
16 void dfs(int x,int y,int cnt)
17 {
18     int i;
19     if(cnt==t)//剪枝:到时间了符合条件ok=1再退出,不符合条件直接退出。
20     {
21         if(ex==x&&ey==y)ok=1;
22         return;
23     }
24     if(ok)return;//找到解后还有部分在继续搜索,这条是为了让其它搜索停止
25
26     for(i=0;i<4;i++)
27     {
28         int fx=x+dir[i][0];
29         int fy=y+dir[i][1];
30         if(fx>=0&&fx<n&&fy>=0&&fy<m&&map[fx][fy]!=‘X‘)
31         {
32             map[fx][fy]=‘X‘;
33             dfs(fx,fy,cnt+1);
34             map[fx][fy]=‘.‘; //回溯
35         }
36     }
37 }
38 int main()
39 {
40     int i,j;
41     //freopen("in.txt","r",stdin);
42     while(scanf("%d%d%d",&n,&m,&t))
43     {
44         if (m == 0 && n == 0 & t == 0)
45             break ;
46
47         for(i=0;i<n;i++)
48         {
49             scanf("%s",map[i]);
50             for(j=0;map[i][j]!=‘\0‘;j++)
51             {
52                 if(map[i][j]==‘S‘)
53                 {
54                     sx=i;sy=j;
55                 }
56                 else if(map[i][j]==‘D‘)
57                 {
58                     ex=i;ey=j;
59                 }
60
61             }
62         }
63         if(abs(sx - ex) + abs(sy - ey) > t || (sx +sy+ex+ey+t)%2 == 1)//如果步数大于时间 或步数的奇偶性不一致
64             printf("NO\n");
65         else
66         {
67             ok=0;
68             map[sx][sy]=‘X‘;
69             dfs(sx,sy,0);
70             if(ok)printf("YES\n");
71             else printf("NO\n");
72         }
73     }
74     return 0;
75 }

时间: 2024-10-16 20:33:45

hdu 1010 dfs 走到终点时刚好花掉所有时间 奇偶性剪枝的相关文章

hdu 1010(DFS) 骨头的诱惑

http://acm.hdu.edu.cn/showproblem.php?pid=1010 题目大意从S出发,问能否在时间t的时候到达终点D,X为障碍 需要注意的是要恰好在t时刻到达,而不是在t时间之内 深搜,注意剪枝 剩下格子大于t时间的时候剪掉这个很好想,但还是会超时,还有一个剪枝是依靠 奇偶性剪枝 比如地图依靠奇偶性是; 0 1 0 1 0 1 1 0 1 0 1 0 0 1 0 1 0 1 1 0 1 0 1 0 0 1 0 1 0 1 可以发现偶数走一步一定到奇数,奇数走一步一定到偶

hdu 1010 dfs+剪枝

Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 119601 Accepted Submission(s): 32313 Problem Description The doggie found a bone in an ancient maze, which fascinated him a lot.

HDU - 1010 (DFS回溯法 + 奇偶剪枝)

题目大意:给出一个N*M的迷宫,迷宫中有一扇门D,只有在T时刻会打开,现在你0时刻位于S,你需要在正好在T时刻到达D,你只能上下左右移动,每次移动耗费1时刻,且同一个位置不能进入两次,问是否能在T时刻刚好到达D处. 范围 1 < N,M < 7, 1 < T < 50,这个范围有点大,直接DFS回溯搜会TLE,我们要加上一个剪枝,这个剪枝十分重要,我们求出起点到终点的距离(横向距离 + 纵向距离),若这个距离为奇数,则时间T必须也要为奇数,否则时间T必须为偶数(其中的道理显而易见)

hdu 1010 dfs搜索

Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 107138    Accepted Submission(s): 29131 Problem Description The doggie found a bone in an ancient maze, which fascinated him a

HDU 1010 Tempter of the Bone(深度+剪枝)

http://acm.hdu.edu.cn/showproblem.php?pid=1010 题意:就是给出了一个迷宫,小狗必须经过指定的步数到达出口,并且每个格子只能走一次. 首先先来介绍一下奇偶性剪枝: 在这道题目中,如果使用剪枝的话,可以节省不少的时间. 在这道题目中,每次dfs循环时都可以判断一下小狗当前位置与终点所相差的步数,如果不为偶数的话,说明到达不了终点,就可以退出这个循环,不必继续dfs了. 在这道题目中,由于每个格子只能经过一次,所以经过一次后,可以把该点位置改为'X',然后

Tempter of the Bone HDU - 1010

Tempter of the Bone HDU - 1010 dfs. 几个剪枝: 1.如果当前所用时间加上当前位置到目标的曼哈顿距离之和大于目标时间,那么显然无论如何不能完成.剪掉 2.在搜索前判一下,如果出发位置到目标的曼哈顿距离与目标时间的奇偶性不同,那么显然无论如何不能完成.剪掉 错误原因:未加第二个剪枝,TLE 1 #include<cstdio> 2 char s[10][10]; 3 bool ok; 4 int n,m,t,tx,ty,sx,sy; 5 int abs(int

HDU 1010 Tempter of the Bone dfs+剪枝

给你一个迷宫一个起点和一个终点,问你能否走T步刚好到达终点,不能重复走,并且只有4个方向 显然这是一个dfs,虽然N最大只有7,但是裸的dfs复杂度还是太高了,因此要进行一些剪枝 1.如果T比图上所有的可走点还要大,肯定是不可行的.这个可以避免dfs整张图. 2.奇偶剪枝,有性质当前点(x,y)到目标点(tx,ty)的所有路径的长度的奇偶性一定和|x-tx|+|y-ty|一样. #include <cstdio> #include <iostream> #include <c

DFS/hdu 1010 Tempter of the Bone

题意 给出一个n*m的地图,s:起点,d:终点,x:障碍物,.:可以走的格子 给出一个时间t,求问是否可以恰好用t时间从起点走到终点.走一步为一个时间. 注意:走过的格子不能再走 注意2:是在时间t刚好到达,而不是时间t以内!也就是说可以在地图上绕远,反正就要在时间t到达! 分析 很普通的深搜,但是有2点剪枝: 1.在刚读入数据后剪枝:当可以走的格子本来就比时间t还短时,必然无法在t时间走到终点 1 if (m*n-xx<=t) //xx is the number of 'X' 2 { 3 p

HDU 1010 Tempter of Bone DFS + 奇偶剪枝

奇偶剪枝: 对于从起始点 s 到达 终点 e,走且只走 t 步的可达性问题的一种剪枝策略. 如下列矩阵 : 从任意 0 到达 任意 0,所需步数均为偶数,到达任意 1 ,均为奇数.反之亦然 所以有,若s走且只走 t 步可到达e,则必有t >= abs(s.x - e.x) + abs(s.y - e.y),且 (t&1) == ((abs(s.x - e.x) + abs(s.y - e.y))&1). 否则必不可达. #include <iostream> #inclu