本文参考洛古中的题解
思路:
如果从迷宫中某一个点出发,走到边界时,可以传送到另一个迷宫矩阵中,但建太多迷宫会增大空间和时间复杂度,所以用取模的形式,
(x,y)=((x+dir+n)%n , (y+dir+m)%m ) )
这样就相当于走到另一个迷宫。
如果某一点在不同的迷宫中被重复走过,那么是有解的
那么如何判断是否在同一个迷宫中?
lx,ly 记录没有取模的x和y值,也就是如果迷宫无限大,x和y真正的值
用vis记录x和y没有取模的值,(lx与ly记录的是最新的值,而vis记录的是上一次的值)
如果此点已经访问过,并且此时的lx,ly不等于vis里面的值,说明不在一个迷宫内,且被重复走过,有解
#include<bits/stdc++.h>
using namespace std;
char f[1504][1505];
int vis[1504][1506][3];
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int n,m;
int fg;
void dfs(int x,int y,int lx,int ly){
if(fg) return ;
if(vis[x][y][0]&&(vis[x][y][1]!=lx||vis[x][y][2]!=ly)){
fg=1;
return ;
}
vis[x][y][0]=1,vis[x][y][1]=lx,vis[x][y][2]=ly;
for(int i=0;i<4;i++){
int u=(x+dir[i][0]+n)%n;
int v=(y+dir[i][1]+m)%m;
int lxx=lx+dir[i][0],lyy=ly+dir[i][1];
if(f[u][v]=='.'){
if(vis[u][v][1]!=lxx||vis[u][v][2]!=lyy||!vis[u][v][0])
dfs(u,v,lxx,lyy);
}
}
}
int main() {
while(cin>>n>>m){
int x,y;
memset(f,'#',sizeof(f));
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>f[i][j];
if(f[i][j]=='S') x=i,y=j,f[i][j]='.';
}
}
fg=0;
dfs(x,y,x,y);
if(fg==1) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
return 0;
}