第一周上H题搜索(Infinite Maze)

We’ve got a rectangular n × m-cell maze. Each cell is either passable, or is a wall (impassable). A little boy found the maze and cyclically tiled a plane with it so that the plane became an infinite maze. Now on this plane cell (x, y) is a wall if and only if cell is a wall.

In this problem is a remainder of dividing number a by number b.

The little boy stood at some cell on the plane and he wondered whether he can walk infinitely far away from his starting position. From cell (x, y) he can go to one of the following cells: (x, y - 1), (x, y + 1), (x - 1, y) and (x + 1, y), provided that the cell he goes to is not a wall.

Input
The first line contains two space-separated integers n and m (1 ≤ n, m ≤ 1500) — the height and the width of the maze that the boy used to cyclically tile the plane.

Each of the next n lines contains m characters — the description of the labyrinth. Each character is either a “#”, that marks a wall, a “.”, that marks a passable cell, or an “S”, that marks the little boy’s starting point.

The starting point is a passable cell. It is guaranteed that character “S” occurs exactly once in the input.

Output
Print “Yes” (without the quotes), if the little boy can walk infinitely far from the starting point. Otherwise, print “No” (without the quotes).

Examples
Input

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

Output

Yes

Input

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

Output

No

Note
In the first sample the little boy can go up for infinitely long as there is a “clear path” that goes vertically. He just needs to repeat the following steps infinitely: up, up, left, up, up, right, up.

In the second sample the vertical path is blocked. The path to the left doesn’t work, too — the next “copy” of the maze traps the boy.

题意:
一个迷宫,由许多基础单元组成,给你基础单元,其中“#”表示墙,“.”表示路,“S“表示起点,问你这个迷宫能不能组成一个无限迷宫,也就是可以不走重复路一直走下去;

题解:
用广搜从起点开始寻找,用走完之后的坐标分别对m和n取余,计算出在基础单元的坐标,然后判断这个坐标是否已经来过了,如果来过了,就说明可以从一个图走到另一个图,符合题意。

代码:

#include"stdio.h"
#include"string.h"
#include"queue"
using namespace std;
struct node
{
    int x,y;
}u,v;
char s[2000][2000];
int book1[2000][2000],book2[2000][2000];//book1用来记录基础单元坐标对应的全部迷宫的x坐标,book2记录y坐标。
int to[4][2]={1,0,-1,0,0,1,0,-1};
int n,m,x,y;
bool bfs()
{
    queue<node>Q;
    u.x=x;
    u.y=y;
    book1[x][y]=x;
    book2[x][y]=y;
    Q.push(u);//起点入队列
    while(!Q.empty())
    {
        u=Q.front();
        Q.pop();
        for(int i=0;i<4;i++)
        {
            v.x=u.x+to[i][0];//迷宫里的坐标,可以大于m,n
            v.y=u.y+to[i][1];
            int tx=(v.x%n+n)%n;//取余后记录基础单元的坐标
            int ty=(v.y%m+m)%m;
            if(s[tx][ty]!='#')//不为墙,可以进行下一步
            {
                if(book1[tx][ty]==999999)//这个点没来过,记录book1,book2
                {
                    book1[tx][ty]=v.x;
                    book2[tx][ty]=v.y;
                    Q.push(v);//这个点入队列
                }
                else if(book1[tx][ty]!=v.x||book2[tx][ty]!=v.y)//如果这个点已经来过了,判断其对应的迷宫的坐标是否和上次相同,若不相同,则说明来到了下一个图
                return 1;
            }
        }
    }
    return 0;
}
int main()
{
    scanf("%d %d",&n,&m);
    for(int i=0;i<n;i++)
    {
       	scanf("%s",s[i]);
       	for(int j=0;j<m;j++)
        {
           	if(s[i][j]=='S')
            {
               	x=i;
               	y=j;
           	}
           	book1[i][j]=999999;//初始化为最大值
           	book2[i][j]=999999;
    	}
    }
    if(bfs())//从起点开始寻找
    printf("Yes\n");
   	else
    printf("No\n");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值