You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

77 lines
2.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
const int N = 1510;//题目要求是1500
//https://www.cnblogs.com/tomori/p/14320956.html
int n, m;
char g[N][N]; //邻接矩阵,也就是二维数据保存地图
int st[N][N][3]; // st[u][v][0~2]分别表示是否访问过x和y
//走迷宫下右上左
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
/**
* 功能:正数+负数取模
*/
int MOD(int a, int b) {
return (a % b + b) % b;
}
bool success;
/**
* 功能:在邻接矩阵上面的深度优先搜索,从x,y这个点出发是不是能走出幻象迷宫
* @param x
* @param y
* @return
*/
void dfs(int x, int y) {
for (int i = 0; i < 4; i++) { //遍历四个方向
int tx = x + dx[i], ty = y + dy[i]; //得到下一步的坐标
//因为可能出现负数,使用负数取模运算
int r = MOD(tx, n), c = MOD(ty, m);
//有的地方是墙,用'#'表示
if (g[r][c] != '#') {
if (st[r][c][0]) { //如果此位置走过
if (st[r][c][1] != tx || st[r][c][2] != ty) {
success = true; //并且不是从当前的位置过来的,就是有其它一条道路走过来的,表示可以走通
return;
}
} else {
//第一次访问到它指x % n = u, y % m = v的坐标(x, y)。
st[r][c][0] = 1, st[r][c][1] = tx, st[r][c][2] = ty;
//开始递归下一个位置
dfs(tx, ty);
}
}
}
}
int main() {
//循环接收多次,ctrl+d结束
while (cin >> n >> m) {
//清空状态数组
memset(st, 0, sizeof st);
success = false;
int sx, sy;//出发点
//双重循环读入地图
// 注意i是从0开始到n-1结束,这是因为:表示迷宫里(0,0)到(n-1,m-1)这个矩阵单元。
// 注意j是从0开始到m-1结束,这是因为:表示迷宫里(0,0)到(n-1,m-1)这个矩阵单元。
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++) {
cin >> g[i][j];
//记录出发点
if (g[i][j] == 'S') sx = i, sy = j;
}
//第一次访问到它指x % n = u, y % m = v的坐标(x, y)。
st[sx][sy][0] = 1, st[sx][sy][1] = sx, st[sx][sy][2] = sy;
//深度优先搜索
dfs(sx, sy);
if (success)cout << "Yes" << endl; //可以走出幻象迷宫
else cout << "No" << endl; //不能走出幻象迷宫
}
return 0;
}