无穷迷宫 & 幻象迷宫

无穷迷宫

&\&

幻象迷宫

题目链接:

1. 无穷迷宫:jzoj 3924jzoj\ 3924
2. 幻象迷宫:luogu 1363luogu\ 1363

无尽迷宫:

题目

传说有一个无穷大的迷宫,这个迷宫实际上是将一个长方形的迷宫无限复制得到的。长方形的迷宫有NNMM列个格子。每个格子要么是空地,要么是墙。大迷宫的每个格子(x,y)(x, y)和格子(x mod N,y mod M)(x\ mod\ N, y\ mod\ M)是相同的。(x mod Nx\ mod\ Nxx 除以 NN 的余数)
一个机器人现在站在位置(x,y)(x, y)的格子。每一步,机器人可以移动到上下左右相邻的空地。而且它从不会走到已经走过的位置。请你判断机器人能否在迷宫中无穷地走下去。

输入

第一行,一个整数TT,表示有TT组测试数据。
接下来若干行,分别描述每组数据。
每组数据的第一行是两个整数NN , MM .
接下来是NN行,每行是MM个字符的字符串,描述一个长方形迷宫的所有格子。空地用.‘.’表示,墙用#‘\#’表示,机器人所在位置用S‘S’表示。

输出

输出TT行,每行一个字符串,依次表示每组测试数据的结果。如果机器人能无穷走下去输出Yes”Yes”,否则输出No”No”

样例解释(样例在下面)

第一组测试数据中,机器人不断沿着路径向上走即可。
第二组测试数据中,机器人无论向哪个方向走都会是死路。

数据范围

50% ⁣50\%\! 的数据:1 ⁣<= ⁣N,M ⁣ ⁣<= ⁣50.1\! <=\! N, M\! \!<=\! 50.
100% ⁣100\%\! 的数据:1 ⁣<= ⁣N,M ⁣<= ⁣15001 ⁣<= ⁣T ⁣<= ⁣4.1 \!<= \!N, M \!<=\! 1500,1\! <=\! T\! <=\! 4.

幻想迷宫:

题目背景

(喵星人LHXLHXWDWD同心协力击退了汪星人的入侵,不幸的是,汪星人撤退之前给它们制造了一片幻象迷宫。)

W ⁣DW\!D:呜呜,肿么办啊……

LH ⁣XLH\!Xmomo...momo...我们一定能走出去的!

W ⁣DW\!D:嗯,+U ⁣ ⁣+ ⁣U+U\!\!+\!U!

题目

幻象迷宫可以认为是无限大的,不过它由若干个NMN*M的矩阵重复组成。矩阵中有的地方是道路,用.'.'表示;有的地方是墙,用#'\#'表示。LH ⁣XLH\!XW ⁣DW\!D所在的位置用S'S'表示。也就是对于迷宫中的一个点(x,y)(x,y),如果(x mod n,y mod m)(x\ mod\ n,y\ mod\ m).'.'或者S'S',那么这个地方是道路;如果(x mod n,y mod m)(x\ mod\ n,y\ mod\ m)#'\#',那么这个地方是墙。LH ⁣XLH\!XW ⁣DW\!D可以向上下左右四个方向移动,当然不能移动到墙上。

请你告诉LH ⁣XLH\!XW ⁣DW\!D,它们能否走出幻象迷宫(如果它们能走到距离起点无限远处,就认为能走出去)。如果不能的话,LH ⁣XLH\!X就只好启动城堡的毁灭程序了……当然不到万不得已,他不想这么做。。。

输入

输入包含多组数据,以EOFEOF结尾。

每组数据的第一行是两个整数NNMM

接下来是一个NMN*M的字符矩阵,表示迷宫里(0,0)(0,0)(n ⁣ ⁣1,m ⁣ ⁣1)(n\!-\!1,m\!-\!1)这个矩阵单元。

输出

对于每组数据,输出一个字符串,YesYes或者NoNo

数据范围

对于30%30\%的数据,N,M ⁣<= ⁣20N,M\!<=\!20
对于50%50\%的数据,N,M ⁣<= ⁣100N,M\!<=\!100
对于100%100\%的数据,N,M ⁣<= ⁣1500N,M\!<=\!1500,每个测试点不超过1010组数据

共同:(样例在这里)

样例输入

2
5 4
##.#
##S#
#..#
#.##
#..#
5 4
##.#
##S#
#..#
..#.
#.##

样例输出

Yes
No

思路与代码:

思路

这道题就是dfsdfs,一点都不简单的dfsdfs

不能把图复制几倍什么的,因为会有一些恶心的数据,比如这个:

1
5 7
S#..#.#
#..#..#
#.#..#.
#.#.#..
..#.#.#

这个还小,但是按这种方法,就会把你卡死。

所以要用另外的方法,我们可以记录这个人在矩阵中的哪个位置,又在整个迷宫中的哪一个位置。如果这个人现在走到的位置之前走到过(指矩阵中),而且第一次经过和第二次经过的真实位置不一样(指整个迷宫中),那么就可以无限走了。
(因为形成了循环,而要真实位置不要相同,是因为有可能他们只是在两个点之间反复横跳罢了)

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#define rr register

using namespace std;

struct node{
	int x, y, in;
}in[1501][1501];
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
int T, n, m, rx, ry, ans;
bool a[1501][1501];
char c;

bool dfs(int x, int y, int real_x, int real_y) {
    if (in[x][y].in && (in[x][y].x != real_x || in[x][y].y != real_y)) {//形成循环
    	ans = 1;
		return 0;
    }

	in[x][y] = (node){real_x, real_y, 1};//记录
	
	for (int i = 0; i < 4; i++) {//方向
		if(a[(x + dx[i] + n) % n][(y + dy[i] + m) % m]) {//能走
            if(in[(x + dx[i] + n) % n][(y + dy[i] + m) % m].x != real_x + dx[i] || 
            in[(x + dx[i] + n) % n][(y + dy[i] + m) % m].y != real_y + dy[i] || 
            !in[(x + dx[i] + n) % n][(y + dy[i] + m) % m].in)
            //没有走过这个点
                dfs((x + dx[i] + n) % n, (y + dy[i] + m) % m, real_x + dx[i], real_y + dy[i]);
        }
	}
	
	return 0;
}

int main() {
	while (cin >> n >> m) {
		memset(in, 0, sizeof(in));//初始化
		memset(a, 0, sizeof(a));
		
		scanf("%d %d", &n, &m);//读入
		for (rr int i = 0; i < n; i++)
			for (rr int j = 0; j < m; j++) {
				c = getchar();
				while (c != '.' && c != 'S' && c != '#') c = getchar();//读入地图
				if (c == '.' || c == 'S') {//不是障碍物
					a[i][j] = 1;
					if (c == 'S') {//是机器人的位置
						rx = i;
						ry = j;
					}
				}
			}
		
		ans = 0;//初始化
		dfs(rx, ry, rx, ry);//dfs
		
		if (ans) printf("Yes\n");//可以
			else printf("No\n");//不可以
	}
	
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章