Problem Description

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.

SampleInput

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

SampleOutput

NO
YES 最开始看见这题直接看了样例,以为就是询问t时间内能不能走出去,直接写了个BFS过了样例,提交上去WA了=7=,事实证明还是不能偷懒。
题意就是S当前位置,D是门,X是墙,问你能不能刚好在t时刻走到门D那里。
然后就是套DFS,本地测试炸栈,就想到了剪枝一下
 int tp = t - step - abs(dx - x) - abs(dy - y);
if(tp < || tp % == )
return ;

这就是剪枝代码,dx和dy代表门的坐标,x、y为当前坐标,step表示以及走了的步数。

当剩余时间走不到门时结束,这个好理解,难理解的是为什么为奇数是也结束。

因为从s每走一步,一定是x或y进行+1或者-1,要使得t时间刚好走到门d。

最短路径m = |dx - x| + |dy - y|;

两种情况,t < m时,肯定无法到达;

t >= m时,从S到D的行走步骤两部分组成,step = t = m + x;(m为最段路径,x为附加步数);

这x = t - m步一定是从最短路径中的某一步走出去,再回到最短路径的步数,而且二者一定是相等的。

如图,最短路径为橘色所示,附加路径为蓝色所示,把蓝色路径分为走出和走回两部分,无论你怎么添加附加路径,这两部分一定是相等的步数。

所以,x一定得为偶数才能保证从S刚好走到D。

而在剪枝中,tp就是我们的x,只有当tp为偶数时,才继续行走。

完整代码:

 #include <iostream>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <sstream>
#include <iomanip>
#include <map>
#include <stack>
#include <deque>
#include <queue>
#include <vector>
#include <set>
#include <list>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <iterator>
#include <cmath>
#include <bitset>
#include <ctime>
#include <fstream>
#include <limits.h>
#include <numeric> using namespace std; #define F first
#define S second
#define mian main
#define ture true #define MAXN 1000000+5
#define MOD 1000000007
#define PI (acos(-1.0))
#define EPS 1e-6
#define MMT(s) memset(s, 0, sizeof s)
typedef unsigned long long ull;
typedef long long ll;
typedef double db;
typedef long double ldb;
typedef stringstream sstm;
const int INF = 0x3f3f3f3f; int n,m,t,flag,wall;
int sx,sy,dx,dy;
char mp[][];
int vis[][];
int fx[][] = {,,-,,,,,-}; bool check(int x,int y){
if(!vis[x][y] && mp[x][y] != 'X' && x >= && y >= && x < n && y < m){
return true;
}
return false;
} void dfs(int x,int y,int step){
if(flag)
return ;
if(x == dx && y== dy && step == t){
flag = ;
return ;
} int tp = t - step - abs(dx - x) - abs(dy - y);
if(tp < || tp % == )
return ; for(int i = ; i < ; i++){
int next_x = x + fx[i][];
int next_y = y + fx[i][];
if(check(next_x,next_y)){
vis[next_x][next_y] = ;
dfs(next_x,next_y,step+);
if(flag)
return ;
vis[next_x][next_y] = ;
}
}
return ;
} int main(){
ios_base::sync_with_stdio(false);
cout.tie();
cin.tie();
while(cin>>n>>m>>t && n && m && t){
fill(vis[],vis[]+,);
MMT(mp);
flag = , wall = ;
for(int i = ; i < n; i++)
cin>>mp[i];
for(int i = ; i < n; i++){
for(int j = ; j < m; j++){
if(mp[i][j] == 'S')
sx = i,sy = j;
if(mp[i][j] == 'D')
dx = i,dy = j;
if(mp[i][j] == 'X')
wall++;
}
}
if(t < abs(dx - sx) + abs(dy - sy) || t > n*m - wall - ){
cout << "NO" << endl;
continue;
}
vis[sx][sy] = ;
dfs(sx,sy,);
if(flag)
cout << "YES" << endl;
else
cout << "NO" << endl;
} return ;
}

Tempter of the Bone(DFS+剪枝)的更多相关文章

  1. HDU1010:Tempter of the Bone(dfs+剪枝)

    http://acm.hdu.edu.cn/showproblem.php?pid=1010   //题目链接 http://ycool.com/post/ymsvd2s//一个很好理解剪枝思想的博客 ...

  2. Tempter of the Bone dfs+剪枝

    The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it u ...

  3. B - Tempter of the Bone(DFS+剪枝)

    The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it u ...

  4. HDU 1010 Tempter of the Bone --- DFS

    HDU 1010 题目大意:给定你起点S,和终点D,X为墙不可走,问你是否能在 T 时刻恰好到达终点D. 参考: 奇偶剪枝 奇偶剪枝简单解释: 在一个只能往X.Y方向走的方格上,从起点到终点的最短步数 ...

  5. 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 ...

  6. Tempter of the Bone(dfs奇偶剪枝)

    Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Othe ...

  7. M - Tempter of the Bone(DFS,奇偶剪枝)

    M - Tempter of the Bone Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & % ...

  8. hdu1010 Tempter of the Bone —— dfs+奇偶性剪枝

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1010 Tempter of the Bone Time Limit: 2000/1000 MS (Ja ...

  9. HDOJ.1010 Tempter of the Bone (DFS)

    Tempter of the Bone [从零开始DFS(1)] 从零开始DFS HDOJ.1342 Lotto [从零开始DFS(0)] - DFS思想与框架/双重DFS HDOJ.1010 Tem ...

  10. zoj 2110 Tempter of the Bone (dfs)

    Tempter of the Bone Time Limit: 2 Seconds      Memory Limit: 65536 KB The doggie found a bone in an ...

随机推荐

  1. 并查集模板题----P3367 【模板】并查集

    题目描述 如题,现在有一个并查集,你需要完成合并和查询操作. 输入格式 第一行包含两个整数N.M,表示共有N个元素和M个操作. 接下来M行,每行包含三个整数Zi.Xi.Yi 当Zi=1时,将Xi与Yi ...

  2. Python机器学习之数据探索可视化库yellowbrick

    # 背景介绍 从学sklearn时,除了算法的坎要过,还得学习matplotlib可视化,对我的实践应用而言,可视化更重要一些,然而matplotlib的易用性和美观性确实不敢恭维.陆续使用过plot ...

  3. Flutter学习笔记(20)--FloatingActionButton、PopupMenuButton、SimpleDialog、AlertDialog、SnackBar

    如需转载,请注明出处:Flutter学习笔记(20)--FloatingActionButton.PopupMenuButton.SimpleDialog.AlertDialog.SnackBar F ...

  4. 数据算法 --hadoop/spark数据处理技巧 --(13.朴素贝叶斯 14.情感分析)

    十三.朴素贝叶斯 朴素贝叶斯是一个线性分类器.处理数值数据时,最好使用聚类技术(eg:K均值)和k-近邻方法,不过对于名字.符号.电子邮件和文本的分类,则最好使用概率方法,朴素贝叶斯就可以.在某些情况 ...

  5. mysql 显示表名和表数量

    SELECT count(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA='dbname'; SELECT * FROM informatio ...

  6. 2015-11-17 linux基础笔记

    21. 可执行权限不代表能够执行,这得看文件内容 22. 还是可以用适当的拓展名表示该文件是什么种类的*.sh  脚本或批处理文件 *Z.*.tar.*.tar.gz.*.zip.*.tgz 压缩文件 ...

  7. ts 学习笔记 - 泛型

    目录 泛型 举个栗子 泛型约束 多个参数时也可以在泛型约束中使用类型参数 泛型接口 泛型类 泛型参数的默认类型 泛型 泛型(Generics)是指在定义函数.接口或者类的时候, 不预先指定其类型,而是 ...

  8. 驰骋工作流引擎与jFinal集成版本2.0

    驰骋工作流引擎与jFinal集成版本2.0 发布说明 关键字: 驰骋工作流程快速开发平台 工作流程管理系统java工作流引擎. 使用协议:GPL. 关于JFinal: https://www.jfin ...

  9. docker An error occurred 虚拟化错误解决

    问题: 本人电脑上装了VMware和docker,系统是win10专业版,然后今天想用下docker,打开报错,Hyper-V未开启,开启之后再次报错 An error occurred Hardwa ...

  10. CentOS -- Zookeeper installation and configure

    1 JDK 1.8 must installed first 2 Get Zookeeper package wget https://archive.apache.org/dist/zookeepe ...