AcWing 1112 迷宫

题目描述:

一天Extense在森林里探险的时候不小心走入了一个迷宫,迷宫可以看成是由 n∗n的格点组成,每个格点只有2种状态,.#,前者表示可以通行后者表示不能通行。

同时当Extense处在某个格点时,他只能移动到东南西北(或者说上下左右)四个方向之一的相邻格点上,Extense想要从点A走到点B,问在不走出迷宫的情况下能不能办到。

如果起点或者终点有一个不能通行(为#),则看成无法办到。

注意:A、B不一定是两个不同的点。

输入格式

第1行是测试数据的组数 k,后面跟着 k 组输入。

每组测试数据的第1行是一个正整数 n,表示迷宫的规模是 n∗n 的。

接下来是一个 n∗n 的矩阵,矩阵中的元素为.或者#

再接下来一行是 4 个整数 ha,la,hb,lb,描述 AA 处在第 ha 行, 第 la 列,BB 处在第 hb 行, 第 lb 列。

注意到 ha,la,hb,lb全部是从 0 开始计数的。

输出格式

k行,每行输出对应一个输入。

能办到则输出“YES”,否则输出“NO”。

数据范围

1≤n≤100

输入样例:

2
3
.##
..#
#..
0 0 2 2
5
.....
###.#
..#..
###..
...#.
0 0 4 0

输出样例:

YES
NO

分析:

本题同样是Flood Fill问题,不过只用求连通性而不用求最短距离,这时DFS更加有优势,只要不爆栈,DFS可以一直深入直到走到终点,而BFS差不多要遍历完所有的状态,比较不划算。本题要注意后台数据的起点和终点位置都可能有障碍物,这时候就是不连通的了;另外,已经走过的点必须要置为已访问,下次遇见不再扩展,不然重复搜索效率极低。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 105;
char g[N][N];
bool st[N][N];
int n,x1,y1,x2,y2;
int dx[] = {1,0,-1,0};
int dy[] = {0,1,0,-1};
bool dfs(int x,int y){
    if(g[x][y] == '#')  return false;
    if(x == x2 && y == y2)  return true;
    st[x][y] = true;
    for(int i = 0;i < 4;i++){
        int nx = x + dx[i],ny = y + dy[i];
        if(nx < 0 || ny < 0 || nx >= n || ny >= n || st[nx][ny])   continue;
        if(dfs(nx,ny))  return true;
    }
    return false;
}
int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(int i = 0;i < n;i++)    scanf("%s",g[i]);
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        memset(st,false,sizeof st);
        if(dfs(x1,y1))   puts("YES");
        else    puts("NO");
    }
    return 0;
}
发布了335 篇原创文章 · 获赞 35 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_30277239/article/details/104777617
今日推荐