杭电 HDU 1010 Tempter of the Bone

题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=1010


问题:在 N*M的迷宫里,小狗要在‘S’的位置,要再第T秒到达出口 'D'  (1 < N, M < 7; 0 < T < 50)。 即求存在路径,果断深搜DFS。


限制条件及剪枝:

1、走过的地方 ‘ . ’不能再走

2、不能通过墙‘X’

3、不能离开地图范围

4、可根据狗到门的最短距离和时间相比较,当时间与最短步骤都为奇数或偶数时,才有可能到达门处,否则永远无法正好在T秒到达门处。(奇偶剪枝,能去掉很多情况,减少时间)

5、找到任何一条存在路径后即可结束搜索并输出。(减少多余的搜索)


一开始第四点没有想到,总是超时,估计没有想到第四点的绝大多数都会超时的。


AC代码:

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

using namespace std;

struct Node
{
    int x,y;
    int time;
};

char map[10][10];
int t;
bool yorn;
int dir[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};

void Dfs(Node now)
{
 //   printf("%d %d %d %d %c\n",now.x,now.y,now.time,yorn,map[now.x][now.y]);
    Node next;
    char ch;
    int i;
    if(yorn)
    {
        return ;
    }
    if(now.time > t)
    {
        return ;
    }
    if(now.time == t)
    {
        if(map[now.x][now.y] == 'D')
        {
            yorn = 1;
        }
        return ;
    }
    for(i = 0; i < 4; i++)
    {
        next.x = now.x+dir[i][0];
        next.y = now.y+dir[i][1];
        next.time = now.time+1;
        if(map[next.x][next.y] != 'X')
        {
            if(map[next.x][next.y] == '.')
            {
                map[next.x][next.y] = 'X';
                Dfs(next);
                map[next.x][next.y] = '.';
            }
            else
            {
                Dfs(next);
            }

        }
    }
}

int main()
{
    int n,m,p;
    int i,j,x,y;
    Node now;
    while(scanf("%d%d%d",&n,&m,&t))
    {
        if(n == 0 && m == 0 && t == 0)
        {
            break;
        }
        memset(map,'X',sizeof(map));  //初始化都为墙
        yorn = 0;
        for(i = 1; i <= n; i++)
        {
            for(j = 1; j <= m; j++)
            {
                cin >> map[i][j];
                if(map[i][j] == 'S')
                {
                    now.x = i;
                    now.y = j;
                }
                if(map[i][j] == 'D')
                {
                    x = i;
                    y = j;
                }
            }
        }
        now.time = 0;
        p = abs(now.x-x) + abs(now.y-y);
        map[now.x][now.y] = 'X';
//        printf("%d\n",yorn);
        if(p%2 == t%2)    //时间和需要走的步骤都为奇数或偶数则搜索(奇偶剪枝)
        {
            Dfs(now);
        }
 //       printf("%d\n",yorn);
        if(yorn > 0)
        {
            printf("YES\n");
        }
        else
        {
            printf("NO\n");
        }
    }

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值