CF196B解题报告
CF196B 解题报告
题意
给定长宽分别为 \(n,m\) 的迷宫 \(a\)。
这个迷宫从顶部可以通向底部,同理从左边可以通向右边。即是有无限个这样的迷宫接在四个方向的。问你是否能在这个迷宫中走到无限远的地方。
分析
因为要走到无限远的地方,所以这个迷宫肯定能通过上边到达下边然后回到起点,左右同理。把迷宫拼起来后发现,如果 \(s_{0,j}\) 可以走,那么 \(s_{n,j}\) 肯定也可以走,左右同理。
之后直接从起点开始暴搜,判断是否满足条件。只要有一条合法路径,那么就能走到无限远。
考虑 dfs,可以直接使用 bool
类型函数判断到这个点是否有合法路径。dfs 中注意坐标的边界,当 \((x,y)\) 越过边界后,通过 \(((x-1)\bmod n + n) \bmod n + 1\) 来更新 \(x\),\(((y-1) \bmod m + m) \bmod m + 1\) 来更新 \(y\)。
#include <bits/stdc++.h>
using namespace std;
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
int n, m, sx, sy;
int vis[1505][1505], wx[1505][1505], wy[1505][1505];
string s[1505];
bool dfs(int x, int y){
int nx = ((x - 1) % n + n) % n + 1;//更新
int ny = ((y - 1) % m + m) % m + 1;
if (s[nx][ny]) return 0;
if (vis[nx][ny]) return wx[nx][ny] != x || wy[nx][ny] != y;//类似于判环,是否有几条路径走到这
wx[nx][ny] = x, wy[nx][ny] = y;//记录一种到达(x,y)的情况
vis[nx][ny] = 1;//标记走过
for (int i = 0; i < 4; i++){
if (dfs(x + dx[i], y + dy[i])) return 1;
}
return 0;
}
int main(){
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++){
cin >> s[i];
s[i] = ' ' + s[i];
for (int j = 1; j <= s[i].size(); j++){
if (s[i][j] == 'S') sx = i, sy = j;
}
}
if (dfs(sx, sy)) printf("Yes");//有一条路径满足
else printf("No");
return 0;
}