Tempter of the Bone 回溯法 还有奇偶剪枝

简介: Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 78529    Accepted...

Tempter of the Bone

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 78529    Accepted Submission(s): 21432


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
 

Recommend
JGShining   |   We have carefully selected several similar problems for you:   1016  1241  1072  1312  1026 
 


这道题啊,折磨了我好久,开始觉得,哦,BFS做就好了,但是范例能过,而实际上却不是合适办法,所以如果对于这道题还是有疑问的同学,只要看看这样一副图就好了。

2 4 7
S..D
....
所以最后参考大神们的代码,解决了本题中的关键问题。
这幅图的答案应该是yes,但是BFS的特点,就是只会保持同一层的而不能像DFS一样将整条路都递归出来,这样的好处是因为本题不能回头,所以每一条路的寻找都不能影响到其他的路径的寻找,每一次标记然后递归后要把标记去掉,所以这道题用回溯法。而且还有奇偶剪枝。

对于奇偶剪枝因为如果对于任何一个位置所在,还需要走的距离是奇数而剩下的时间是偶数,那么可以直接不考虑这条路了,主人公活不了的。直接return掉好了。

所以需要这样来避免时间上被卡住。

代码君

#include<cstdio>
#include<cmath>
#include<cstring>

using namespace std;
int   vid[9][9];
char  way[9][9];
int m,n,t;
bool flag = false;
struct Steps{
    int x,y;
};
Steps   walk,en;
const int mov[4][2] = {0,1,0,-1,1,0,-1,0};
void backtrack(int bx,int by,int ust){
    int need;
    if(flag)
        return;
    if(ust == t){
        if(bx == en.x && by == en.y){
            flag = true;
            return;
        }
    }
    need = fabs(bx - en.x)+fabs(by - en.y);
    int temp = t - ust - need;
    if(temp < 0||temp&1){
        return;
    }
    for(int i = 0;i < 4;i++){
        int tx,ty;
        tx = bx + mov[i][0];
        ty = by + mov[i][1];
        if(tx >= 0 && ty >= 0 && tx < n && ty < m && (way[ty][tx] == '.' || way[ty][tx] == 'D') && !vid[ty][tx]){
            vid[ty][tx] = 1;
            backtrack(tx,ty,ust+1);
            vid[ty][tx] = 0;
        }
    }
}
int main(){
    while(~scanf("%d %d %d",&m,&n,&t) && m){
        memset(way,'X',sizeof(way));
        flag = false;
        for(int i = 0;i < m;i++){
            for(int j = 0;j < n;j++){
                scanf(" %c",&way[i][j]);
                if(way[i][j] == 'S'){
                    walk.x = j;
                    walk.y = i;
                }
                if(way[i][j] == 'D'){
                    en.x = j;
                    en.y = i;
                }
            }
        }
        memset(vid,0,sizeof(vid));
        vid[walk.y][walk.x] = 1;
        backtrack(walk.x,walk.y,0);
        if(flag)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return  0;
}


相关文章
|
8月前
螺旋矩阵~
螺旋矩阵~
|
Java
「日更刷题」59.螺旋矩阵
「日更刷题」59.螺旋矩阵
80 0
AtCoder Beginner Contest 216 D - Pair of Balls (思维建图 拓扑排序判断有向图是否有环)
AtCoder Beginner Contest 216 D - Pair of Balls (思维建图 拓扑排序判断有向图是否有环)
129 0
|
机器学习/深度学习 算法
【刷穿 LeetCode】求「连通图经过所有点的最短路径」的三种方式 :「BFS」&「Floyd + 状压 DP」 &「AStar 算法」
【刷穿 LeetCode】求「连通图经过所有点的最短路径」的三种方式 :「BFS」&「Floyd + 状压 DP」 &「AStar 算法」
【HDU】1175 连连看(BFS + 剪枝)
【HDU】1175 连连看(BFS + 剪枝)
271 0
【HDU】1175 连连看(BFS + 剪枝)
|
C语言
HDOJ/HDU Tempter of the Bone(深搜+奇偶性剪枝)
HDOJ/HDU Tempter of the Bone(深搜+奇偶性剪枝)
103 0
|
算法
回溯法解决N皇后问题
来源: 维基百科-N皇后问题 解题思路 采用回溯法,即逐一位置放置,然后放置下一行,如果下一行没有合法位置,则回溯到上一行,调整位置,直到得到所有值. 实现代码 /** * solve the N-Queen problem */ public class NQueen { //the ...
2508 0
|
算法
使用LINGO来解决0/1背包算法问题
原文:使用LINGO来解决0/1背包算法问题 1.问题说明   0/1背包问题:我们有n种物品,物品j的重量为wj,价格为pj。我们假定所有物品的重量和价格都是非负的。背包所能承受的最大重量为W。如果限定每种物品只能选择0个或1个,则问题称为0-1背包问题。
2017 0