奇偶剪枝***&&***HDU1010 Tempter of the Bone
2013-05-24 13:03
417 查看
Link Here :*****奇偶原理详解
Link Here:*****HDU 1010
现假设起点为(sx,sy),终点为(ex,ey),给定t步恰好走到终点,
如图所示(“|”竖走,“—”横走,“+”转弯),易证abs(ex-sx)+abs(ey-sy)为此问题类中任意情况下,起点到终点的最短步数,记做step,此处step1=8;
如图,为一般情况下非最短路径的任意走法举例,step2=14;
step2-step1=6,偏移路径为6,偶数(易证);
返回,false;
反之亦反。
还是以这个为例子吧,现在我把矩阵填满 0 和 1
我们现假设从 0 开始走,则不难证明,
从任意 0 走到任意 1 始终是奇数步;
从任意 0 走到任意 0 始终是偶数步;
引用描述里的“例子”, s 到 e 的最短步数为 t (当然你也可以理解成此时到终点刚好剩余 t 步等等)。
则,我们从 s 到 e 的步数之和(或者说总距离)总可以表示成 sum= t + extra ( extra>=0 ),其中 extra 表示额外的步数。[1]
比如“例子”里面的,做例1吧
此时 t=8,sum=14,所以我们容易得到 extra=6。也就是说按照这个走法,需要在最短的步数上再走额外的 6 步(先不用太在意这些偏移是在什么地方产生的)。
在来一个例2吧,
此时,t=7,sum=15,所以我们也容易得到 extra=8。
根据理科生的天性,由这两个一般性的例子,我们很容易嗅察到 extra 都为偶数。先带着疑惑,
再来看我给的 0 、1 矩阵。
设左上角坐标为(1,1),右下角坐标为(5,5).
那么我们给的例1,
起点 s 的坐标为(1,1),此点为“0”;
终点 e 为(5,5),此点为“0”。
所以t=8,为偶数。
现在我们再倒过来看,从终点(也就是 e )出发,把最短步数 t=8 耗费掉,不妨这样走,
如图所示从 e (5,5)耗费 8 步走到了(1,5)点。
因为是从 0 走偶数步,所以走到的坐标也一定是 0 ,就像这里的(1,5)点是 0 一样。
又因为最短步数已经耗费掉了,所以不管怎样,从(1,5)再走回到起点 s 所用的步数总是最开始从起点 s 走到终点 e 所花的某一个额外步数 extra 。
注意到,(1,5)点和起点 s (1,1)都是 0,也就是说,这个 extra 必然是偶数!
再看例2,同样从终点 e 开始耗费 t=7 步,
则所到的点一定是 0 (不管她在哪里),再从这个点回到起点 s ,所用的 extra 也必然是个偶数!
所以无论如何,sum= t + extra ( extra>=0 ) 中的 extra 都是一个偶数
那么我们就可以用公式 t-[abs(ex-sx)+abs(ey-sy)] 计算出extra是否为偶数来判断当前点能否恰好在这么多步到达终点了。
有的同学可能会说以 1 为 起点呢。。其实是一样的啦,自己去捣鼓吧。
现在明白了么。。那么我再给个经典的实例吧,自己去试着做一下 ZOJ 2110 或者 HDU 1010。
合作编辑者
Z钟氏家族
更多
Link Here:*****HDU 1010
奇偶剪枝
描述
奇偶剪枝是数据结构的搜索中,剪枝的一种特殊小技巧。现假设起点为(sx,sy),终点为(ex,ey),给定t步恰好走到终点,
s | ||||
| | ||||
| | | |||
| | ||||
+ | — | — | — | e |
s | — | — | — | |
— | — | + | ||
| | + | |||
| | ||||
+ | — | — | — | e |
step2-step1=6,偏移路径为6,偶数(易证);
结论
推广之,若 t-[abs(ex-sx)+abs(ey-sy)] 结果为非偶数(奇数),则无法在t步恰好到达;返回,false;
反之亦反。
原理补充
鉴于很多同学对奇偶剪枝根本原理的兴趣,所以hj决定再补充一下本词条。还是以这个为例子吧,现在我把矩阵填满 0 和 1
0 | 1 | 0 | 1 | 0 |
1 | 0 | 1 | 0 | 1 |
0 | 1 | 0 | 1 | 0 |
1 | 0 | 1 | 0 | 1 |
0 | 1 | 0 | 1 | 0 |
从任意 0 走到任意 1 始终是奇数步;
从任意 0 走到任意 0 始终是偶数步;
引用描述里的“例子”, s 到 e 的最短步数为 t (当然你也可以理解成此时到终点刚好剩余 t 步等等)。
则,我们从 s 到 e 的步数之和(或者说总距离)总可以表示成 sum= t + extra ( extra>=0 ),其中 extra 表示额外的步数。[1]
比如“例子”里面的,做例1吧
s | — | — | — | |
— | — | + | ||
| | + | |||
| | ||||
+ | — | — | — | e |
在来一个例2吧,
s | — | — | — | |
— | — | + | ||
| | + | |||
| | | + | — | e |
+ | — | — |
根据理科生的天性,由这两个一般性的例子,我们很容易嗅察到 extra 都为偶数。先带着疑惑,
再来看我给的 0 、1 矩阵。
0 | 1 | 0 | 1 | 0 |
1 | 0 | 1 | 0 | 1 |
0 | 1 | 0 | 1 | 0 |
1 | 0 | 1 | 0 | 1 |
0 | 1 | 0 | 1 | 0 |
那么我们给的例1,
起点 s 的坐标为(1,1),此点为“0”;
终点 e 为(5,5),此点为“0”。
所以t=8,为偶数。
现在我们再倒过来看,从终点(也就是 e )出发,把最短步数 t=8 耗费掉,不妨这样走,
s | | | + | |
| | + | — | |
| | ||||
+ | — | |||
— | — | e |
因为是从 0 走偶数步,所以走到的坐标也一定是 0 ,就像这里的(1,5)点是 0 一样。
又因为最短步数已经耗费掉了,所以不管怎样,从(1,5)再走回到起点 s 所用的步数总是最开始从起点 s 走到终点 e 所花的某一个额外步数 extra 。
注意到,(1,5)点和起点 s (1,1)都是 0,也就是说,这个 extra 必然是偶数!
再看例2,同样从终点 e 开始耗费 t=7 步,
则所到的点一定是 0 (不管她在哪里),再从这个点回到起点 s ,所用的 extra 也必然是个偶数!
所以无论如何,sum= t + extra ( extra>=0 ) 中的 extra 都是一个偶数
那么我们就可以用公式 t-[abs(ex-sx)+abs(ey-sy)] 计算出extra是否为偶数来判断当前点能否恰好在这么多步到达终点了。
有的同学可能会说以 1 为 起点呢。。其实是一样的啦,自己去捣鼓吧。
现在明白了么。。那么我再给个经典的实例吧,自己去试着做一下 ZOJ 2110 或者 HDU 1010。
合作编辑者
Z钟氏家族
更多
#include <stdio.h> #include <stdlib.h> char map[8][8]; int n,m,s,e,T; bool flag = false; int dir[5][3]={{1,0},{0,1},{-1,0},{0,-1}}; void DFS(int u,int v,int step) { if(u==s&&v==e&&step==T) flag = true; if(flag)return ; if(step > T)return ; int res=T-step-(abs(u-s)+abs(v-e)); if(res < 0||res&1)return ; //额外的步数比理论上的最短路径还短||额外步数不为偶数 //if((T-step<0)||(T-step)%2!=(abs(u-s)+abs(v-e)))return; for(int i = 0;i < 4;i++) { int x = u + dir[i][0]; int y = v + dir[i][1]; if(x>=0&&x<n&&y>=0&&y<m&&map[x][y]!='X') { map[x][y] = 'X';//****1 DFS(x,y,step+1); map[x][y] = '.';//****2 //次二处乃使DFS的精髓所在 } } } int main() { while(scanf("%d%d%d",&n,&m,&T),(n+m+T)) { for(int i = 0;i < n;i++) scanf("%s",map[i]); int u,v,TotStep = 0; for(int i = 0;i < n;i++) for(int j = 0;j < m;j++) { if(map[i][j] == 'S') { u = i; v = j; }else if(map[i][j] == 'D') { s = i; e = j; TotStep++; }else if(map[i][j] == '.') { TotStep++; } } flag = false; map[u][v] = 'X'; if(T <= TotStep) DFS(u,v,0); if(flag) puts("YES"); else puts("NO"); } return 0; }
相关文章推荐
- HDU1010 Tempter of the Bone (DFS & 奇偶剪枝)
- hdu1010 Tempter of the Bone --DFS & 奇偶剪枝
- HDU 1010 && ZOJ 2110 Tempter of the bone (DFS + 奇偶剪枝)
- HDU 1010 && ZOJ 2110--Tempter of the Bone【DFS && 奇偶剪枝】
- HDOJ1010 Tempter of the Bone(DFS+奇偶剪枝)
- HDU1010——Tempter of the Bone(深度搜索,奇偶剪枝)
- HDU 1010 Tempter of the Bone (DFS 奇偶剪枝)
- HDOJ 1010 Tempter of the Bone(搜索,奇偶剪枝)
- zoj(2110)Tempter of the Bone(DFS+奇偶剪枝)
- zoj 2110 Tempter of the Bone(DFS+奇偶剪枝及优化操作)
- hdu 1010 Tempter of the Bone(dfs+奇偶剪枝)
- hdu 1010 Tempter of the Bone (dfs+奇偶剪枝)
- hdu 1010 Tempter of the Bone (dfs+奇偶剪枝)
- Tempter of the Bone(dfs+奇偶剪枝)
- Tempter of the Bone-深度优先中的奇偶剪枝问题
- hdoj 1010 Tempter of the Bone 【DFS】+【奇偶剪枝】
- HDU 1010 Tempter of the Bone(dfs+奇偶剪枝)
- 4000 HDU 1010 - Tempter of the Bone(DFS 奇偶剪枝)
- hdu 1010 Tempter of the Bone(深搜+奇偶剪枝)
- hdu 1010:Tempter of the Bone(DFS + 奇偶剪枝)