【题目描述】
一天Extense在森林里探险的时候不小心走入了一个迷宫,迷宫可以看成是由n×n的格点组成,每个格点只有2种状态,.和#,前者表示可以通行后者表示不能通行。同时当Extense处在某个格点时,他只能移动到东南西北(或者说上下左右)四个方向之一的相邻格点上,Extense想要从点A走到点B,问在不走出迷宫的情况下能不能办到。如果起点或者终点有一个不能通行(为#),则看成无法办到。
【输入】
第1行是测试数据的组数k,后面跟着k组输入。每组测试数据的第1行是一个正整数n(1≤n≤100),表示迷宫的规模是n×n的。接下来是一个n×n的矩阵,矩阵中的元素为.或者#。再接下来一行是4
个整数ha,la,hb,lb,描述A处在第ha行, 第la列,B处在第hb行, 第lb列。注意到ha,la,hb,lb全部是从0
开始计数的。【输出】
k行,每行输出对应一个输入。能办到则输出“YES”,否则输出“NO”。
【输入样例】
2
3
.##
..#
#..
0 0 2 2
5
.....
###.#
..#..
###..
...#.
0 0 4 0【输出样例】
YES
NO
【题解代码】
解法一:dfs
#include<bits/stdc++.h> //万能头文件
using namespace std;const int N = 1e3 + 10;
char g[N][N]; //迷宫数组
int n; //迷宫大小
int sx, sy, tx, ty; //起点和终点的坐标
int flag; //标记是否到达
bool vis[N][N]; //标记数组
//方向数组
int dx[] = { -1,1,0,0 };
int dy[] = { 0,0,-1,1 };void dfs(int px, int py )
{if (px == tx && py == ty) //当前搜素的点是终点{flag = true; //标记找到return; //结束}for (int i = 0; i < 4; i++) //搜索当前点的邻接点{int bx = px + dx[i]; int by = py + dy[i];if (bx<1 || bx>n || by<1 || by>n)continue; //越界,跳过本次搜索if (g[bx][by] == '#')continue; //遇到障碍物,跳过本次搜索if (vis[bx][by] == 1)continue; //已经搜索过,跳过本次搜索vis[bx][by] = 1; //除上述不能搜索的情况外,标记并搜索dfs(bx, by);}
}int main()
{int k; cin >> k;while(k--){cin >> n;for (int i = 1; i <= n; i++){for (int j = 1; j <= n; j++){cin >> g[i][j];}}cin >> sx >> sy >> tx >> ty;sx++, sy++, tx++, ty++; //本题中的起始位置从0开始,创建的数组从1开始,通过++同步flag = false; //假设找不到memset(vis, 0, sizeof vis); //标记数组清空vis[sx][sy] = 1; //将起始位置标记dfs(sx, sy);if (flag){cout << "YES" << endl;}else{cout << "NO" << endl;}}return 0;
}
解法二:bfs
#include<bits/stdc++.h> //万能头文件
using namespace std;const int N = 1e3 + 10;
char g[N][N]; //迷宫数组
int n; //迷宫大小
int sx, sy, tx, ty; //起点和终点的坐标
int flag; //标记是否到达
bool vis[N][N]; //标记数组
//方向数组
int dx[] = { -1,1,0,0 };
int dy[] = { 0,0,-1,1 };struct point
{int x, y;
};void bfs(point s)
{queue<point> q;q.push(s); //起点入队while (!q.empty()){point cur = q.front();q.pop();if (cur.x == tx && cur.y == ty) //当前搜索点是终点{flag = true; //标记return; //结束}for (int i = 0; i < 4; i++){int bx = cur.x + dx[i]; int by = cur.y + dy[i];if (bx<1 || bx>n || by<1 || by>n)continue; //越界,跳过本次搜索if (g[bx][by] == '#')continue; //遇到障碍物,跳过本次搜索if (vis[bx][by] == 1)continue; //已经搜索过,跳过本次搜索vis[bx][by] = 1; //除上述不能搜索的情况外,标记并搜索q.push({ bx,by });}}
}int main()
{int k; cin >> k;while (k--){cin >> n;for (int i = 1; i <= n; i++){for (int j = 1; j <= n; j++){cin >> g[i][j];}}cin >> sx >> sy >> tx >> ty;sx++, sy++, tx++, ty++; //本题中的起始位置从0开始,创建的数组从1开始,通过++同步flag = false; //假设找不到memset(vis, 0, sizeof vis); //标记数组清空vis[sx][sy] = 1; //将起始位置标记bfs({ sx, sy });if (flag){cout << "YES" << endl;}else{cout << "NO" << endl;}}return 0;
}