牛客——小A与小B (双向广搜)

小A与小B

https://ac.nowcoder.com/acm/problem/23486

牛客——小A与小B (双向广搜)

题意:

迷宫,小A每次可以移动一个位置,而小B每次可以移动两次位置,小A移动的方向是上下左右左上左下右上右下8个方向,小B移动的方向是上下左右4个方向,请问他们最早什么时候能够找到对方,如果他们最终无法相遇,那么就输出”NO"。

思路:

双向广搜经典问题

将A和B的起始位置都加到队列里,同时跑BFS,判断走过的位置是否已经被对方走过,如果走过的话,说明已经相遇了,输出即可。

要注意A和B走的方向和步数不一样。

代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int>PII;
#define I_int ll
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
char F[200];
inline void out(I_int x) {
    if (x == 0) return (void) (putchar('0'));
    I_int tmp = x > 0 ? x : -x;
    if (x < 0) putchar('-');
    int cnt = 0;
    while (tmp > 0) {
        F[cnt++] = tmp % 10 + '0';
        tmp /= 10;
    }
    while (cnt > 0) putchar(F[--cnt]);
    cout<<endl;
}

const int maxn=1100;

char mp[maxn][maxn];
struct node{
    int x,y;
};
queue<node>q[2];
int vis[2][maxn][maxn];
int n,m;
int sx,sy,ex,ey;
int nx[] = {1, -1, 0, 0, 1, -1, -1, 1};
int ny[] = {0, 0, 1, -1, -1, 1, -1, 1};
bool bfs(int u){
    int tt=q[u].size();
    while(tt--){
        node t=q[u].front();
        q[u].pop();
        if(u==0){
            for(int i=0;i<8;i++){
                int xx=t.x+nx[i],yy=t.y+ny[i];
                if(xx<1||yy<1||xx>n||yy>m||mp[xx][yy]=='#')
                    continue;
                if(!vis[u][xx][yy]){
                    if(vis[u^1][xx][yy])    return true;
                    vis[u][xx][yy] = 1;
                    q[u].push({xx,yy});
                }
            }
        }
        else{
            for(int i=0;i<4;i++){
                int xx=t.x+nx[i],yy=t.y+ny[i];
                if(xx<1||yy<1||xx>n||yy>m||mp[xx][yy]=='#')
                    continue;
                if(!vis[u][xx][yy]){
                    if(vis[u^1][xx][yy])    return true;
                    vis[u][xx][yy] = 1;
                    q[u].push({xx,yy});
                }
            }
        }
    }
    return 0;
}

int sol(){
    int res=0;
    vis[0][sx][sy]=1;vis[1][ex][ey]=1;
    q[0].push({sx,sy});q[1].push({ex,ey});
    while(!q[0].empty()||!q[1].empty()){
        res++;
        if(bfs(0)) return res;
        if(bfs(1)) return res;
        if(bfs(1)) return res;
    }
    return -1;
}

int main(){
    scanf("%d %d", &n, &m);
    getchar();
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>mp[i][j];
            if(mp[i][j]=='C'){
                sx=i,sy=j;
            }
            else if(mp[i][j]=='D'){
                ex=i,ey=j;
            }
        }
    }
    int tmp=sol();
    if(tmp==-1) puts("NO");
    else{
        puts("YES");
        cout<<tmp<<endl;
    }
    return 0;
}
全部评论
同时搜,相遇后为什么直接返回res就是最短时间?如果有多个点相遇呢?
点赞 回复 分享
发布于 2020-09-04 09:23

相关推荐

牛客83265014...:完了,连现在都没开始面,13号投的是不是晚了
秋招的第一个offer,...
点赞 评论 收藏
分享
搜索部&nbsp;首先说下timeline8.18,投递8.19,约一面8.21,晚上一面call约二面8.22,上午二面下午oc周末等待(8.23,8.24)8.25,offer一年前,我还是懵懵懂懂,高考完的暑假,只会提前学学高数,未来的画像是什么?我或许无法预测。开学后,自学Python,接单,无数个客户的ddl,偷偷摸摸一个人找自习的地方,这一步步竟然为后来的我,搭建工程能力的基础。大一上,我也要感谢我的第一位老板,让我接触到了实习,师兄带着我一步步入门,看他们写的飞书文档。大一下,导师带我参与企业项目,这让我渐渐发现,应该去实践,增长见识,而非局限当下,盯着自己的小新pro。不久后,第一波投递开始,结果当然是约面极少。盯着简历上的文字和ssob,我开始思考,确实很多可以去提升。带着些许不甘心,继续沉淀,慢慢的约面也越来越多,有的时候两天7场,准备完就接着下一个日程。这一次,也许是刚好到位吧,比较match,面试答的流利,关关难关关过,成为度孝子展望未来,依然是重重挑战,果然只有收到offer的那一刻是开心的。愿在百度星海拆解的每一段代码,都能成为丈量宇宙的诗行;此志终赴星河,而今迈步重铸天阶。屏幕前的你们,在无数个向星海奔赴的日夜,一定一定,会在未来化作群星回响的征程——请永远相信此刻埋首耕耘的自己!!!
一天三顿半:???百度提前批发 offer了?不是统一和正式批排序完再发吗我靠
百度求职进展汇总
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务