HDU 1010 Tempter of the Bone

#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;

char map[9][9];
int n, m, t, di, dj;
int dir[4][2] = {{0,-1}, {0, 1}, {1, 0}, {-1, 0}};//四个方向
bool escape;

void dfs(int si, int sj, int cnt)
{
    int i, temp;
    if (si>n || si<=0 || sj>m || sj<=0) //边界
        return ;
    if (si == di && sj == dj && cnt == t)   //成功逃脱,必须要恰好到达
    {
        escape = true;
        return ;
    }
    // (t-cnt) 到终点还需要的步数
    // abs(si-di)+abs(sj-dj) 当前点到终点的步数
    temp = (t-cnt)-(abs(si-di)+abs(sj-dj));
    if (temp < 0 || temp%2)
        return ;
    for (i=0; i<4; ++i)
    {
        if (map[si+dir[i][0]][sj+dir[i][1]] != 'X')
        {
            map[si+dir[i][0]][sj+dir[i][1]] = 'X';  //把走过的设置为墙壁,就不能走了
            dfs(si+dir[i][0], sj+dir[i][1], cnt+1);
            if (escape)
                return ;
            map[si+dir[i][0]][sj+dir[i][1]] = '.';  //恢复现场
        }
    }
    return ;
}

int main()
{
    int i, j, si, sj;
    while (cin >> n >> m >> t)
    {
        if (n==0 && m==0 && t==0)
            break;
        int wall = 0;
        for (i=1; i<=n; ++i)
            for (j=1; j<=m; ++j)
            {
                cin >> map[i][j];
                if (map[i][j] == 'S')   // (si, sj) 起始位置
                {
                    si = i;
                    sj = j;
                }
                else if (map[i][j] == 'D') // (di, dj) 目标位置
                {
                    di = i;
                    dj = j;
                }
                else if (map[i][j] == 'X')
                    ++wall; //墙壁数量
            }
        if (n*m-wall <= t) // (n*m-wall) 表示一共可以走的步数
        {
            cout << "NO" << endl;
            continue;
        }
        escape = false;
        map[si][sj] = 'X';
        dfs(si, sj, 0);
        if (escape)
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值