HUSTOJ 基础题组3 问题 B: 手机的诱惑

题目描述

张晨乐在一个古老的迷宫中发现了一个手机,这个手机深深地吸引了他。

然而,当他拾起手机,迷宫开始摇晃,张晨乐能感觉到地面下沉。他意识到:这个手机只是一个诱饵!于是,他不顾一切地试图冲出这个迷宫。

迷宫是一个大小为N*M的矩形,有一扇门,一开始,门是关闭的,并在第T秒打开一瞬间(小于1秒的时间)。因此,张晨乐必须刚好在第T秒钟到达门口。
每一秒,他都可以向上,下,左,右四个相邻的位置中的任意一个移动。一旦他进入一个新的地方,这个地方的地面就会开始下沉,并在下一秒消失。因此,他不能在一个地方停留超过一秒钟,也不能再进入曾经走过的地方。

请问,可怜的张晨乐能够逃出迷宫吗?

输入

输入由多个测试用例组成。
每个测试用例的第一行包含三个整数N,M和T(1 <N,M <7; 0 <T <50),分别表示迷宫的大小和门打开的时间。
接下来的N行给出迷宫布局,每行包含M个字符。

每个字符含义如下:

'X':不能进入的墙
'S':起点
'D':门
'.':可以行走的地方

输入以三个0结束,这个测试用例不被处理。

输出

对于每组测试数据,如果张晨乐能够逃出迷宫,则请输出“YES”,否则,请输出“NO”。每组数据输出占一行。

样例输入 Copy
4 4 5
S.X.
..X.
..XD
....
3 4 5
S.X.
..X.
...D
0 0 0
样例输出 Copy
NO
YES
#include<iostream>
using namespace std;
 
int vis[9][9] = { 0 };
char map[9][9];
int mov[4][2] = { {1,0},{0,1},{-1,0},{0,-1} };
int row, col, Time;
int wall_numbers;
int start_x, start_y;
int end_x, end_y;
int flag = 0;
 
void dfs(int start_x, int start_y, int steps) {
    if (start_x<1 || start_x>row || start_y<1 || start_y>col)return;
    if (map[start_x][start_y] == 'X')return;
    if (start_x == end_x && start_y == end_y && steps == Time) {
        flag = 1;
        return;
    }
 
    //获取下一个点的位置
    int next_x, next_y;
    for (int i = 0; i < 4; i++) {
        next_x = start_x + mov[i][0];
        next_y = start_y + mov[i][1];
        if (vis[next_x][next_y])continue;
        vis[next_x][next_y] = 1;
        dfs(next_x, next_y, steps + 1);
        vis[next_x][next_y] = 0;
    }
}
 
int main()
{
    while (cin >> row >> col >> Time) {
        if (row == 0 && col == 0 && Time == 0)
            break;
        //初始化
        for (int i = 0; i < 9; i++)
            for (int j = 0; j < 9; j++)
                vis[i][j] = 0;
        wall_numbers = 0;
        flag = 0;
 
        getchar();
        //读入地图数据
        for (int i = 1; i <= row; i++) {
            for (int j = 1; j <= col; j++) {
                scanf("%c", &map[i][j]);
            }
            getchar();
        }
                 
 
        //寻找起始点,终点,统计墙面数量
        for(int i = 1;i<=row;i++)
            for (int j = 1; j <= col; j++) {
                if (map[i][j] == 'S') {
                    start_x = i;
                    start_y = j;
                }
                if (map[i][j] == 'X') {
                    wall_numbers++;
                }
                if (map[i][j] == 'D') {
                    end_x = i;
                    end_y = j;
                }
            }
 
        //奇偶性剪枝
        if ((start_x + start_y) % 2 && (end_x + end_y) % 2) {
            if (Time % 2) {
                cout << "NO" << endl;
                continue;
            }
        }
        if ((start_x + start_y) % 2 == 0 && (end_x + end_y) % 2 == 0) {
            if (Time % 2) {
                cout << "NO" << endl;
                continue;
            }
        }
        if ((start_x + start_y) % 2 == 0 && (end_x + end_y) % 2) {
            if (!(Time % 2)) {
                cout << "NO" << endl;
                continue;
            }
        }
        if ((start_x + start_y) % 2  && (end_x + end_y) % 2 == 0) {
            if (!(Time % 2)) {
                cout << "NO" << endl;
                continue;
            }
        }
         
        if (row * col - wall_numbers <= Time) {
            cout << "NO" << endl;
            continue;
        }
 
        //DFS算法
        vis[start_x][start_y] = 1;
        dfs(start_x, start_y, 0);
 
        if (flag)
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值