洛谷 P1363 幻象迷宫

题目传送门

如果某一个点被在不同的矩阵上走过两次,那就一定可以走出无限远.

因为有模运算的骚操作,所以只需要保存一张矩阵即可.

#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\n");
		else
			printf("No\n");
	}
	return 0;
}
posted @ 2020-11-05 21:06  Mr^Simon  阅读(63)  评论(0编辑  收藏  举报