膨胀的tyx 题解

前言
个人感觉比较有意思的一道题,思路还是挺巧妙的,到了lydd那里就变成中规中矩的题了
题目描述
由于tyx抱过了这么多大腿,他变得越来越棒棒了,一般的迷宫根本拦不住他。为了治一治他,你决定为他单独定制一款无限迷宫。

所谓无限迷宫是指,由一个 的迷宫单元经过无限平铺得到的迷宫,即将无数份迷宫单元平铺在一个二维平面上。定制好以后,你将tyx扔到了迷宫里,不妨假定tyx落在了起点处。

出于对无限迷宫的恐惧,tyx想要尽可能逃离这里。那么问题来了,tyx能不能逃到距离起点无限远的地方去呢?

输入格式
第一行两个整数 ,用来描述迷宫单元的尺寸。

接下来是一个 的字符矩阵,用来描述这个迷宫,每个字符一定属于以下三种:

字符’.'代表这个点是空地。

字符’S’代表这个点是起点。

字符’#'代表这个点是墙,不可以走。

输出格式
输出一行一个字符串“Yes”或“No”(不包括引号),“Yes”表示tyx可以逃到无限远的地方,“No”表示不可以。

样例
样例输入1
3 3
#.#
#.#
#S#
样例输出1
Yes
样例输入2
5 5
#.#.#
…#.S

…#…
#.#.#
样例输出2
No


一开先我的思路是就在图里跑,到了边界如果对边有对应的入口就穿越到那里,如果最后回到起点就说明不行
但这个思路在第一个样例就过不去了,再考虑一下文中说的"无限"两字,发现只要最后到达在初始迷宫中同一个位置时,不是初始地图就可以逃脱,因为它可以用相同的路线跑到下一个此位置,然后无限远离起点
定义每个位置的坐标为x,y,bx,by,其中bx和by表示以初始地图为参照物的其他地图的位置,用bix数组和biy数组存下每个初始地图中的点的坐标,进行比较就行了
code:

#include<cstdio>
#include<iostream>
#include<queue>
using namespace std;
int sx,sy,n,m,bix[2005][2005],biy[2005][2005];
char mp[2005][2005];
bool vis[2005][2005];
const int dx[]={1,-1,0,0};
const int dy[]={0,0,1,-1};
struct ren{
	int x,y,bx,by;
}st;
queue<ren> q;
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
		cin>>mp[i][j];
		if(mp[i][j]=='S')
		{
			sx=i;
			sy=j;
		}
	    }	
	}
	st.x=sx;
	st.y=sy;
	q.push(st);
	while(!q.empty())
	{
		ren now=q.front();
		q.pop();
		for(int i=0;i<4;i++)
		{
			ren b=now;
			int nowx=b.x+dx[i],nowy=b.y+dy[i];
			//边界处理
			if(nowx>m)
			{
				nowx-=n;
				b.bx++;
			}
			else if(nowx==0)
			{
				nowx+=n;
				b.bx--;
			}
			else if(nowy>n)
			{
				nowy-=m;
				b.by++;
			}
			else if(nowy==0)
			{
				nowy+=m;
				b.by--;
			}
			b.x=nowx;
			b.y=nowy;
			if(mp[nowx][nowy]=='#')
			{
				continue;
			}
			if(!vis[nowx][nowy])
			{
				vis[nowx][nowy]=1;
				bix[nowx][nowy]=b.bx;
				biy[nowx][nowy]=b.by;
				q.push(b);
			}
			else if(b.bx!=bix[nowx][nowy]||b.by!=biy[nowx][nowy])
			{
				printf("Yes\n");
				return 0;
			}
		}
	}
	printf("No\n");
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值