DFS中的奇偶剪枝(技巧)
剪枝是什么,简单的说就是把不可行的一些情况剪掉,例如走迷宫时运用回溯法,遇到死胡同时回溯,造成程序运行时间长。剪枝的概念,其实就跟走迷宫避开死胡同差不多。若我们把搜索的过程看成是对一棵树的遍历,那么剪枝顾名思义,就是将树中的一些“死胡同”,不能到达我们需要的解的枝条“剪”掉,以减少搜索的时间。
这里介绍一下奇偶剪枝
什么是奇偶剪枝?
部分内容来自https://blog.csdn.net/chyshnu/article/details/6171758
把矩阵看成如下形式:
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
从为 0 的格子走一步,必然走向为 1 的格子 。
从为 1 的格子走一步,必然走向为 0 的格子 。
即:
从 0 走向 1 必然是奇数步,从 0 走向 0 必然是偶数步。
所以当遇到从 0 走向 0 但是要求时间是奇数的或者 从 1 走向 0 但是要求时间是偶数的,都可以直接判断不可达!
比如一张地图c
- S...
- ....
- ....
- ....
- ...D
要求从S点到达D点,此时,从S到D的最短距离为s = abs ( dx - sx ) + abs ( dy - sy )。
如果地图中出现了不能经过的障碍物:
- S..X
- XX.X
- ...X
- .XXX
- ...D
此时的最短距离s' = s + 4,为了绕开障碍,不管偏移几个点,偏移的距离都是最短距离s加上一个偶数距离。
就如同上面说的矩阵,要求你从0走到0,无论你怎么绕,永远都是最短距离(偶数步)加上某个偶数步;要求你从1走到0,永远只能是最短距离(奇数步)加上某个偶数步。
例题
Tempter of the Bone
The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it up, the maze began to shake, and the doggie could feel the ground sinking. He realized that the bone was a trap, and he tried desperately to get out of this maze.
The
maze was a rectangle with sizes N by M. There was a door in the maze. At
the beginning, the door was closed and it would open at the T-th second
for a short period of time (less than 1 second). Therefore the doggie
had to arrive at the door on exactly the T-th second. In every second,
he could move one block to one of the upper, lower, left and right
neighboring blocks. Once he entered a block, the ground of this block
would start to sink and disappear in the next second. He could not stay
at one block for more than one second, nor could he move into a visited
block. Can the poor doggie survive? Please help him.
Input
The input consists of multiple
test cases. The first line of each test case contains three integers N,
M, and T (1 < N, M < 7; 0 < T < 50), which denote the sizes
of the maze and the time at which the door will open, respectively. The
next N lines give the maze layout, with each line containing M
characters. A character is one of the following:
'X': a block of wall, which the doggie cannot enter;
'S': the start point of the doggie;
'D': the Door; or
'.': an empty block.
The input is terminated with three 0's. This test case is not to be processed.
Output
For each test case, print in one line "YES" if the doggie can survive, or "NO" otherwise.
Sample Input
4 4 5
S.X.
..X.
..XD
....
3 4 5
S.X.
..X.
...D
0 0 0
Sample Output
NO
YES
题目意思:给定你起点S,和终点D,问你是否能在 T 时刻恰好到达终点D。
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int map[][];
int a,b,c,d,flag;
int n,m,t,count;
int dir[][]= {{,-},{,},{,},{-,}}; ///分别表示左、右、下、上四个方向
void DFS(int x,int y,int count)
{
int k,p,q,i;
if(x>n||y>m||x<||y<)
{
return ;
}
if(count==t&&x==c&&y==d)///时间正好才能逃生
{
flag=;
return ;
}
k=(t-count)-(abs(x-c)+abs(y-d))/*当前点到终点的最短路*/;///k为当前点到终点最短路还需要的时间差
if(k<||k&)///k<0或者为奇数则不可能到达
{
return ;
}
for(i=; i<; i++)
{
p=x+dir[i][];
q=y+dir[i][];
if(map[p][q]!='X')
{
map[p][q]='X';
DFS(p,q,count+);
if(flag)
{
return ;
}
map[p][q]='.';///搜索不到则退出,重新将该点刷成。
}
}
return ;
}
int main()
{
int w,i,j;///墙的数量
while(scanf("%d%d%d",&n,&m,&t)!=EOF)
{
getchar();
w=;
if(n==&&m==&&t==)
{
break;
}
for(i=; i<=n; i++)
{
for(j=; j<=m; j++)
{
scanf("%c",&map[i][j]);
if(map[i][j]=='S')///记录狗的位置
{
a=i;
b=j;
}
else if(map[i][j]=='D')///出口的位置
{
c=i;
d=j;
}
else if(map[i][j]=='X')///墙的数量
{
w++;
}
}
getchar();
}
if(n*m-w<=t)///路径剪切,走完了不含墙的迷宫都还不到时间t,迷宫塌陷
{
printf("NO\n");
}
else
{
flag=;
map[a][b]='X';///将狗的起始位置刷为x
DFS(a,b,);///这里的DFS函数是一个需要自身调用自身的递归函数,需要设置参数
if(flag==)
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
}
return ;
}
DFS中的奇偶剪枝(技巧)的更多相关文章
- DFS中的奇偶剪枝学习笔记
奇偶剪枝学习笔记 描述 编辑 现假设起点为(sx,sy),终点为(ex,ey),给定t步恰好走到终点, s | | | + — — — e 如图所示(“|”竖走,“—”横走,“+”转弯),易证abs( ...
- HDU 1010 Tempter of the Bone【DFS经典题+奇偶剪枝详解】
Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
- HDU1010 Tempter of the Bone【小狗是否能逃生----DFS奇偶剪枝(t时刻恰好到达)】
Tempter of the Bone Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u ...
- HDU 1010 Tempter of the Bone (DFS+可行性奇偶剪枝)
<题目链接> 题目大意:一个迷宫,给定一个起点和终点,以及一些障碍物,所有的点走过一次后就不能再走(该点会下陷).现在问你,是否能从起点在时间恰好为t的时候走到终点. 解题分析:本题恰好要 ...
- hdoj1010 奇偶剪枝+DFS
Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
- Tempter of the Bone(dfs奇偶剪枝)
Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
- hdu 1010:Tempter of the Bone(DFS + 奇偶剪枝)
Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
- HDU 1010 (DFS搜索+奇偶剪枝)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1010 题目大意:给定起点和终点,问刚好在t步时能否到达终点. 解题思路: 4个剪枝. ①dep&g ...
- hdoj 1010 Tempter of the Bone【dfs查找能否在规定步数时从起点到达终点】【奇偶剪枝】
Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Othe ...
随机推荐
- diff命令--比较两个文件的命令
可以使用 --brief 来比较两个文件是否相同,使用 -c参数来比较这两个文件的详细不同之处,这绝对是判断文件是否被篡改的有力神器,
- AML与PIO整合问题
要想把PIO引擎封装成AML组件,面临如下问题(逐渐补充): 1)版本不兼容 内容项 AML PIO 选型 兼容? JDK 1.7 1.8 1.8 是 SPARK 1.6.1 2.1.1 HA ...
- 面试题——Java虚拟机
一.运行时数据区域 Java虚拟机在执行Java程序的时候会把它所管理的内存划分为若干个不同的数据区域,这些区域各有用途: 程序计数器:(线程私有的) 程序计数器是一块较小的内存,可以看作是当前线程所 ...
- WIN10下WNMP开发环境部署
刚刚开始学习PHP时,一直使用phpstudy,后面发现很多东西自己单独配置安装会理解更深刻,所以自己总结了一下windows下开发环境的部署教程. 以前经常在CSDN和博客园看别人的教程,今天才注册 ...
- JS通用弹窗,确定,取消可以回调方法。
<html> <head> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/j ...
- SpaceVim 语言模块 dart
原文连接: https://spacevim.org/cn/layers/lang/dart/ 模块简介 功能特性 依赖安装及启用模块 启用模块 语法检查及代码格式化 安装 dart-repl 快捷键 ...
- 20145234黄斐《网络对抗技术》实验一,逆向及Bof基础实践
实践内容 本次实践的对象是一个名为hf20145234的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串. 该程序同时包含另一个代码片段, ...
- [Jmeter]用Jmeter做压力测试(分布式)
Jmeter 是Java应用,对于CPU和内存的消耗比较大,因此,当需要模拟数以千计的并发用户时,使用单台机器模拟所有的并发用户就有些力不从心,甚至会引起JAVA内存溢出错误.为了让jmeter工具提 ...
- Android AOSP 单独编译某一模块
由于AOSP 项目太大,我只修改了一个模块,比如设置. 那么只需要单独编译设置这个模块就可以了. 首先执行Source: source build/envsetup.sh 执行之后,就会有一些额外的命 ...
- HI-2110的657sp3版本应用笔记之TUP
1. TUP是什么? TUP是华为的搞的一套封装了标准Coap的函数,底层是Coap,上层是华为封装的一层收发函数,用来简化Coap的收发流程,最终只用6个函数搞定,不用懂Coap就可以的. 2. T ...