题意 :
地址这里
就是一张没有尽头可以延生的图上搜索
分析:
我们需要求解这张图是否能无限走。
如何判断呢:我们可以发现如果一个点被走了两次显然是可以无限的。
但是如何判断走了两次呢
我们需要一个 取膜的坐标 (x,y) 和一个没有去膜的坐标 (lx,ly)
我们要用 (lx,ly) 来判断,我们只需要正常赋值这个坐标,因为第一个坐标是会被取膜的。
所以只要两个坐标不同时,且这个点已经被走了两次,显然这张图是符合题意的。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cctype>
#define maxn 2000
using namespace std;
const int dx[4] = {1,-1,0,0};
const int dy[4] = {0,0,1,-1};
inline int read() {
int x = 0 ;char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
int n,m,sx,sy,flag;
int map[maxn][maxn],vis[maxn][maxn][3];
char c;
inline void dfs(int x,int y,int lx,int ly) {
if(flag) return;
if(vis[x][y][0] && (vis[x][y][1] != lx || vis[x][y][2] != ly)) {
//若不取膜的坐标和取膜的坐标不同且这个被第二次访问,则说明存在无限
flag = 1;
return;
}
vis[x][y][1] = lx,vis[x][y][2] = ly,vis[x][y][0] = 1;
for(int i=0;i<4;i++) {
int xx = (x + dx[i] + n) % n,yy = (y + dy[i] + m)%m;
int lxx = lx + dx[i],lyy = ly + dy[i];
if(!map[xx][yy]) {
if(vis[xx][yy][1] != lxx || vis[xx][yy][2] != lyy || !vis[xx][yy][0])
dfs(xx,yy,lxx,lyy);
}
}
}
int main() {
while(cin>>n>>m) {
memset(map,0,sizeof(map));
memset(vis,0,sizeof(vis));
flag = 0;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++) {
cin>>c;
if(c == 'S') sx=i,sy=j;
if(c == '#') map[i][j] = 1;
}
dfs(sx,sy,sx,sy);
if(flag) puts("Yes");
else puts("No");
}
return 0;
}