D - Infinite Maze (BFS) Codeforces Round #124 (Div. 2)

题目大意:

       一个n*m的地图无限复制,问能否远离出发点。

题目思路:

       只要走到两张不同图的同一个位置,那么说明可以一直走下去,因为 走到的是两张不同图的同一位置,所以一个位置还可以到另一个不同图的相同位置,如此可以已知走下去。

       做的时候没想到,后来看题解,这也是看过一份思路最厉害的。

        每个node除了记录x,y还记录cx,cy。   

        cx表示上下方向穿越的次数,cy表示所有方向穿越的次数。vis_x和vis_y数组表示走到过这个点的cx,cy,如果发现这个点走过,而且和上次记录的穿越次数不一样,那么就YES

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN=3005;
int n,m;
char C[MAXN][MAXN];
int vis[MAXN][MAXN],vis_x[MAXN][MAXN],vis_y[MAXN][MAXN];
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
struct node
{
    int x,y,cx,cy;
    node(){}
    node(int a,int b,int c,int d){
        x=a,y=b;cx=c;cy=d;
    }
};
queue<node>q2;
bool check(int x,int y)
{
    if(C[x][y]!='#'&&x>=1&&x<=n&&y>=1&&y<=m){
        return 1;
    }
    return 0;
}
int bfs(int sx,int sy)
{
    queue<node>q;
    while(!q.empty())q.pop();
    q.push(node(sx,sy,0,0));
    vis[sx][sy]=1;vis_x[sx][sy]=0;vis_y[sx][sy]=0;
    while(!q.empty())
    {
        node now=q.front();
        q.pop();
        for(int i=0;i<4;i++){
            int xx=dx[i]+now.x;
            int yy=dy[i]+now.y;
            int c_x=now.cx,c_y=now.cy;
            if(xx<=0){
                c_x--;xx=n;
            }
            if(xx>=n+1){
                c_x++;xx=1;
            }
            if(yy<=0){
                c_y--;yy=m;
            }
            if(yy>=m+1){
                c_y++;yy=1;
            }
            if(vis[xx][yy]&&check(xx,yy))
                if(c_x!=vis_x[xx][yy]||c_y!=vis_y[xx][yy])return 1;
            if(!vis[xx][yy]&&check(xx,yy)){
                q.push(node(xx,yy,c_x,c_y));
                vis[xx][yy]=1;vis_x[xx][yy]=c_x;vis_y[xx][yy]=c_y;
            }
        }
    }
    return 0;
}
int main()
{
    scanf("%d%d",&n,&m);
    int sx,sy;
    for(int i=1;i<=n;i++){
        scanf("%s",C[i]+1);
        for(int j=1;j<=m;j++){
            if(C[i][j]=='S'){
                sx=i,sy=j;
            }
        }
    }
    if(bfs(sx,sy))printf("Yes\n");
    else printf("No\n");

}
/*
5 5
#.#.#
.S#..
#####
..#..
#.#.#
*/

       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值