您的位置:首页 > 其它

hdu1010 Tempter of the Bone dfs搜索 剪枝

2017-03-02 18:03 411 查看


Tempter of the Bone

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 116519 Accepted Submission(s): 31594



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.

Sample Input

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


Sample Output

NO
YES


Author

ZHANG, Zheng

Source

ZJCPC2004

题意:可怜小狗误入迷宫陷阱,这个古代迷宫陷阱危险重重,每走一步脚下的石板便会下陷,消失不再。而唯一的出口,只会在一个确定某一秒打开,求问可怜的小狗是否能逃脱赶回家观看小嶋阳菜的毕业live(雾)

刚开始没有看清题目就去用bfs写了,wa了一下自己后看了一下题,这个迷宫的门仅仅在特定的某一秒打开的,bfs用来存最短路,但并不符合这题的意思。所以只用深搜,然而这题需要大剪枝,当前时间已经过了大门打开的时间的话这个水都想的到
然而还是超时呢,搜题解瞧瞧发现了一个奇淫技巧

两个点之间的曼哈顿距离是偶数的话,从起点到终点无论怎么绕圈子,是一定要用偶数步才能到达终点的。奇数也是同理。

所以在搜索的时候要计算门打开的时间距当下的时间的差值,然后计算当前点和终点的曼哈顿距离,判读两者的奇偶性是否相同,不相同直接剪掉

关于奇偶步数请看这个博客

代码实现这个博客实现的比较好

下面是我的代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
int dx[4] = {0,0,1,-1};
int dy[4] = {1,-1,0,0};
const int inf = 0x3f3f3f3f;
const int maxn = 10;
char save[maxn][maxn];
int d[maxn][maxn];
int n,m,t;
bool flag,judge;
pair<int,int> start,ed;
void dfs(int x,int y,int time){
if(flag){
return;
}
int i;
time++;
if(time>t||(abs(x-ed.first)+abs(y-ed.second)+t-time)%2!=0){
return;
}
save[x][y] = 'X';
if(time==t&&x==ed.first&&y==ed.second){
flag = true;
}
for(i=0;i<4;i++){
int nx = x+dx[i];
int ny = y+dy[i];
if(nx>=1&&nx<=n&&ny>=1&&ny<=m&&save[nx][ny]!='X'){
dfs(nx, ny, time);
}
}
save[x][y] = '.';
}

int main(){
int i,j;
while(~scanf("%d%d%d",&n,&m,&t)&&n){
getchar();
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
scanf("%c",&save[i][j]);
if(save[i][j]=='S'){
start = make_pair(i, j);
}
if(save[i][j]=='D'){
ed = make_pair(i, j);
}
}
getchar();
}
flag = false;
dfs(start.first, start.second, -1);
if(flag){
printf("YES\n");
}else{
printf("NO\n");
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: