hdu 1010 Tempter of the Bone

hdu 1010 的传送门

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.
题目大意:就是求从S点开始到达D点需要的时间跟给出的时间相比是不是相等,(不要走带有”X”的地方)如果相等输出YES,不相等输出NO。。
解题思路:剪枝 + 深搜,,注意这里是奇偶剪枝,奇偶剪枝:
是数据结构的搜索中,剪枝的一种特殊小技巧。
现假设起点为(sx,sy),终点为(ex,ey),给定t步恰好走到终点,
 
s
|
|
|
+ — — — e

如图所示(“|”竖走,“—”横走,“+”转弯),易证abs(ex-sx)+abs(ey-sy)为此问题类中任意情况下,起点到终点的最短步数,记做step,此处step1=8;
  
s — — —
— — +
| +
|
+ — — — e

如图,为一般情况下非最短路径的任意走法举例,step2=14;
step2-step1=6,偏移路径为6,偶数(易证);
故,若t-[abs(ex-sx)+abs(ey-sy)]结果为非偶数(奇数),则无法在t步恰好到达;
返回,false;
反之亦反。
上代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
using namespace std;
char map[15][15];
bool vis[15][15];
int m,n,k,ans;
int ax,ay,bx,by;
int flag,step;
int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
void dfs(int x, int y, int cnt)
{
    int mx,my;
    if(x == bx && y == by)
    {
        if(k == cnt)
           flag=1;
        return ;
    }
    if(cnt>=k)
       return ;
    if(map[x][y]!='X')
    {
        for(int i=0; i<4; i++)
        {
            mx=x+dir[i][0];
            my=y+dir[i][1];
            if(mx>=1&&mx<=m && my>=1&&my<=n && !vis[mx][my] && map[mx][my]!='X')
            {
                vis[mx][my]=1;
                dfs(mx,my,cnt+1);
                vis[mx][my]=0;
                if(flag)
                  return;

            }
        }
    }
}

int main()
{
    while(~scanf("%d%d%d",&m, &n, &k),m,n,k)
    {
        int cnt;
        for(int i=1; i<=m; i++)
        {
            for(int j=1; j<=n; j++)
            {
                cin>>map[i][j];
                if(map[i][j] == 'S')
                {
                    ax=i;
                    ay=j;
                }
                if(map[i][j] == 'D')
                {
                    bx=i;
                    by=j;
                }
            }
        }
        memset(vis, 0, sizeof(vis));
        if(abs(ax-bx)+abs(ay-by)>k || (ax+bx+ay+by+k)%2==1)//奇偶剪枝
        {
            puts("NO");
            continue;
        }
        vis[ax][ay]=1;
        flag=0;
        cnt=0;
        dfs(ax, ay, cnt);
        if(flag)
           puts("YES");
        else
           puts("NO");

    }
    return 0;
}
时间: 2024-11-03 02:13:16

hdu 1010 Tempter of the Bone的相关文章

HDOJ/HDU Tempter of the Bone(深搜+奇偶性剪枝)

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 despe

算法:hdu 2639 Bone Collector II (dp 01背包求第k优解)

题目大意: 有n件物品,每件物品有体积和价值两个属性, 一个小偷带着一个大小为v的背包,要 偷这些东西,问小偷能偷的第k大的价值是多少? 思路: 这题和典型的01背包求最优解不同, 是要求第k大的解,所以,最直观的想法就是在01背包的基础上再增加一维,用来保存前k大小的数,然后在 递推时,根据前一个状态的前k 大小的数推出下一个阶段的前k个数保存下来. d[i][j][k], 表示取前i个物品,用j的费用,第k大价值是多少 在递推d[i][j][1...k]时,先获取上一个状态d[i- 1][j

hdu 2639 Bone Collector II (0/1背包)

点击打开链接hdu 2639 思路: 0/1背包求第k优解 分析: 1 其基本思想是,将每个状态都表示成有序队列,将状态转移方程中的 max/min 转 化成有序队列的合并. 2 这里仍然以 01 背包为例讲解一下.    首先看 01 背包求最优解的状态转移方程: F [i, v] = max{F [i − 1, v], F [i − 1, v −Ci ] + Wi }.如果要求第 K 优解,那么状态 F [i, v] 就应该是一个大小为 K 的队列F [i, v, 1 . . . K].其中

hdu 2602 Bone Collector(0/1背包)

点击打开链接hdu 2602 思路: 裸0/1背包 代码: #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N = 1010; const int MAXN = 1000010; int n , sum; int v[N] , w[N] , dp[N]; int solve(){ memset(dp

算法:HDU 4681 String (dp, LCS | 多校8)

题意 给出3个字符串A,B,C,要你找一个字符串D, 要满足下面规定 a) D是A的子序列 b) D是B 的子序列 c) C是D的子串 求D的最大长度 要注意子序列和子串的区别,子序列是不连续的,字串是连 续的 思路 由题目可知,C一定是A和B的子序列,那么先假设C在A和B中只有一个子序列,看下 面例子: abcdefdeg acebdfgh cf 可以看到"cf"在A串的[3, 6]区间 内, 在B串的[2,6]区间(黄色背景) 因为所求的C是D的子串,所以在该黄色区间内的其他字母一

hdu 1198 Farm Irrigation

hdu 1198 的传送门 Sample Input 2 2 DK HF 3 3 ADC FJK IHE -1 -1 Sample Output 2 3 题目大意:有如上图11种土地块,块中的绿色线条为土地块中修好的水渠,现在一片土地由上述的各种土地块组成,需要浇水,问需要打多少口井. 解题思路:用并查集,注意要初始化就好了 #include <iostream> #include <cstring> #include <cstdio> using namespace

HDU 3986 Harry Potter and the Final Battle

链接: http://acm.hdu.edu.cn/showproblem.php?pid=3986 题目: Harry Potter and the Final Battle Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1139    Accepted Submission(s): 359 Problem Description

hdu 1878 欧拉回路

点击打开链接hdu 1878 思路: 欧拉回路 分析: 1 首先题目给定的是一个无向图,所以我们判断该图是欧拉图的条件是图是否是连通的并且所有点的度都是偶数 2 很明显度数很好判断,而图是否连通通过并查集 代码: #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int MAXN = 1010; int fa

hdu 1558 Segment set

点击打开hdu 1558 思路: 计算几何+并查集 分析: 1 有n个操作,最后求有几个集合或者说是连通分量 2 对于输入一条线段我们就去前面找能够和它相交的线段,利用并查集进行合并并且更新rank数组,rank[x]数组保存的是以x为跟节点的集合的线段的数量 3 这一题难点就是线段的相交判断 代码: #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include&