题目传送门
如果某一个点被在不同的矩阵上走过两次,那就一定可以走出无限远.
因为有模运算的骚操作,所以只需要保存一张矩阵即可.
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n,m,xx,yy,vis[1501][1501][2],sum,num;
int dx[] = {-1,0,1,0};
int dy[] = {0,-1,0,1};
bool a[1501][1501],ans,h[1501],li[1501],mx,mxx;
inline void dfs(int x,int y) {
for(int i = 0;i <= 3; i++) {
if(ans) return ;
int x1 = x + dx[i],mx,xx1;
int y1 = y + dy[i],my,yy1;
mx = x1 / n;
my = y1 / m;
xx1 = x1 % n;
yy1 = y1 % m;
if(!a[xx1][yy1]) continue;
if(vis[xx1][yy1][1] == my && vis[xx1][yy1][0] == mx) continue;
if((vis[xx1][yy1][1] != my || vis[xx1][yy1][0] != mx) && vis[xx1][yy1][1] != 0 && vis[xx1][yy1][0] != 0) {
ans = 1;
return ;
}
vis[xx1][yy1][0] = mx;
vis[xx1][yy1][1] = my;
dfs(x1,y1);
}
}
int main() {
while(scanf("%d%d",&n,&m) != EOF) {
string l;
memset(a,0,sizeof(a));
memset(vis,0,sizeof(vis));
memset(li,0,sizeof(li));
memset(h,0,sizeof(h));
sum = num = ans = mx = mxx = 0;
for(int i = 0;i < n; i++) {
cin >> l;
for(int j = 0;j < m; j++) {
if(l[j] == 'S')
xx = i + 10000 * n,yy = j + 10000 * m,a[i][j] = 1;
if(l[j] == '.')
a[i][j] = 1;
}
}
vis[xx%n][yy%m][1] = vis[xx%n][yy%m][0] = 10000;
dfs(xx,yy);
if(ans)
printf("Yes
");
else
printf("No
");
}
return 0;
}