hdu 1010 dfs搜索

Tempter of the Bone

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

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

题目大意是要在那个时间点找到D点,典型的DFS问题,重点是要求奇偶减枝

#include <stdio.h>
#include <math.h>
#include <cmath>
#include <iostream>
using namespace std;
#define Maxn 100

int hang,lie,Time;
char MAP[Maxn][Maxn];
int begin_x,begin_y;
int end_x,end_y;
bool flag;
int dir[4][2] = {
    {0,1},
    {0,-1},
    {1,0},
    {-1,0}
};

void print()
{
    for(int i = 0; i < hang; i++)
    {
        for(int j = 0; j < lie; j++)
        {
            printf("%c",MAP[i][j]);
        }
        printf("\n");
    }
}

void dfs(int x, int y, int t)
{
    // print();
    // printf("\n");
    if (flag)
    {
        return ;
    }
    // printf("Q\n", );
    if (x == end_x && y == end_y && t == Time)
    {
        // printf("YES~~~~~~~~~~~\n");
        flag = true;
        return ;
    }
    int temp = (Time - t) - ( abs(x- end_x) + abs(y - end_y) );
    if (temp < 0 || temp & 1)
    {
        return ; // 奇偶剪枝
        /*要理解奇偶剪枝,先了解一下曼哈顿距离,
        从一个点到达另外一个点的最
        短路径长度(时间)可以根据两点坐标求出,
        路径长度(非最短)与最短路径的长度同奇偶,
        它们的差一定是偶数!举个例子,就像两个偶数的差
        差是偶数,两个个数的差也是偶数.*/
    }
    for(int i = 0; i < 4; i++)
    {
        int xx = x + dir[i][0];
        int yy = y + dir[i][1];
        if (xx >= 0 && xx < hang && yy >= 0 && yy < lie)
        {
            if (MAP[xx][yy] != ‘X‘)
            {
                MAP[xx][yy] = ‘X‘;
                dfs(xx,yy,t+1);
                MAP[xx][yy] = ‘.‘;
            }
        }
    }
    return ;
}

int main()
{
    while(cin >> hang >> lie >> Time,hang + lie + Time)
    {
        flag = false;
        for(int i = 0; i < hang; i++)
        {
            scanf("%s",MAP[i]);
        }
        for(int i = 0; i < hang; i++)
        {
            for(int j = 0; j < lie; j++)
            {
                if (MAP[i][j] == ‘S‘)
                {
                    begin_x = i;
                    begin_y = j;
                }
                else if (MAP[i][j] == ‘D‘)
                {
                    end_x = i;
                    end_y = j;
                }
            }
        }
        // printf("%d %d\n",begin_x,begin_y);
        MAP[begin_x][begin_y] = ‘X‘;
        dfs(begin_x,begin_y,0);
        if (flag)
        {
            printf("YES\n");
        }
        else
        {
            printf("NO\n");
        }
    }
}

  

时间: 2024-08-01 02:36:17

hdu 1010 dfs搜索的相关文章

hdu 1010(DFS) 骨头的诱惑

http://acm.hdu.edu.cn/showproblem.php?pid=1010 题目大意从S出发,问能否在时间t的时候到达终点D,X为障碍 需要注意的是要恰好在t时刻到达,而不是在t时间之内 深搜,注意剪枝 剩下格子大于t时间的时候剪掉这个很好想,但还是会超时,还有一个剪枝是依靠 奇偶性剪枝 比如地图依靠奇偶性是; 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 可以发现偶数走一步一定到奇数,奇数走一步一定到偶

hdu 1010 dfs 走到终点时刚好花掉所有时间 奇偶性剪枝

题意:输入一个n*m的迷宫,和一个T:可以在迷宫中生存的最大时间.S为起点,D为终点.并且,每个格子只能踩一次,且只能维持一秒,然后该块地板就会塌陷.所以你必须每秒走一步,且到D点时,所用时间为T.用深搜.奇偶性剪枝:如果当前的狗所在的坐标与D的坐标奇偶性不一样,那么狗需要走奇数步.同理,如果狗所在坐标与D的坐标奇偶性一样,那么狗需要走偶数步数. 也就是说,狗的坐标x.y和对2取余是它的奇偶性,Dxy和对2取余是D的奇偶性.两个奇偶性一加再对2取余,拿这个余数去与剩下时间对2取余的余数作比较即可

HDU 1045 (DFS搜索)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1045 题目大意:在不是X的地方放O,所有O在没有隔板情况下不能对视(横行和数列),问最多可以放多少个O. 解题思路: 题目规模比较小(4*4),可以DFS解决. 对于一个点,要么放,要么不放. 放的话条件必须是上下左右四个方向扫到边界且不首先碰到X. 可以只对放的点进行标记,而对于不放的点不进行标记,这样当dep>n*n的时候及时return就行了. 注意每次dfs只需要按顺序考虑一个点,而不要同

hdu 1010 dfs+剪枝

Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 119601 Accepted Submission(s): 32313 Problem Description The doggie found a bone in an ancient maze, which fascinated him a lot.

HDU - 1010 (DFS回溯法 + 奇偶剪枝)

题目大意:给出一个N*M的迷宫,迷宫中有一扇门D,只有在T时刻会打开,现在你0时刻位于S,你需要在正好在T时刻到达D,你只能上下左右移动,每次移动耗费1时刻,且同一个位置不能进入两次,问是否能在T时刻刚好到达D处. 范围 1 < N,M < 7, 1 < T < 50,这个范围有点大,直接DFS回溯搜会TLE,我们要加上一个剪枝,这个剪枝十分重要,我们求出起点到终点的距离(横向距离 + 纵向距离),若这个距离为奇数,则时间T必须也要为奇数,否则时间T必须为偶数(其中的道理显而易见)

Tempter of the Bone HDU - 1010

Tempter of the Bone HDU - 1010 dfs. 几个剪枝: 1.如果当前所用时间加上当前位置到目标的曼哈顿距离之和大于目标时间,那么显然无论如何不能完成.剪掉 2.在搜索前判一下,如果出发位置到目标的曼哈顿距离与目标时间的奇偶性不同,那么显然无论如何不能完成.剪掉 错误原因:未加第二个剪枝,TLE 1 #include<cstdio> 2 char s[10][10]; 3 bool ok; 4 int n,m,t,tx,ty,sx,sy; 5 int abs(int

HDU 1010 Tempter of the Bone(DFS+奇偶性剪枝)

Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 70665    Accepted Submission(s): 19487 Problem Description The doggie found a bone in an ancient maze, which fascinated him a

hdu 1518 Square (dfs搜索可参考poj1011)

Square Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 8589    Accepted Submission(s): 2784 Problem Description Given a set of sticks of various lengths, is it possible to join them end-to-end

HDU 1010 Tempter of the Bone dfs+剪枝

给你一个迷宫一个起点和一个终点,问你能否走T步刚好到达终点,不能重复走,并且只有4个方向 显然这是一个dfs,虽然N最大只有7,但是裸的dfs复杂度还是太高了,因此要进行一些剪枝 1.如果T比图上所有的可走点还要大,肯定是不可行的.这个可以避免dfs整张图. 2.奇偶剪枝,有性质当前点(x,y)到目标点(tx,ty)的所有路径的长度的奇偶性一定和|x-tx|+|y-ty|一样. #include <cstdio> #include <iostream> #include <c