题解 | #牛牛走迷宫#

牛牛走迷宫

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

用bfs肯定没有问题,但就是处理 t  + 1和 t + 2,可能第一会想到结构体加优先队列,但这种思路不对,可能会出现下面这种情况
. # # # # # #           步数是  0 # # # # # #
.  .  .  .  .  .  .                        1 2 3 4 5 6 7
# # # # # # #                       # # # # # # #                            
# # # # # # #                       # # # # # # #
# # # # # #  .                       # # # # # # 9
# # # # .  # #                       # # # # 7 # #
# # # # .  .  .                        # # # # 8 9 .对于这最后一个点他上一步可以是上面那个9跳两步过来的时间为11;也可能是右边走过来的10
问题就在于优先队列对于时间相同是无法处理的,这和自己设置的dx和dy的先往哪个方向移动有关
也可能是###9
              #9#.
所以无法通过dx,dy来确定最后一次是移动还是跳跃,故在优先队列的基础上加上移动到这一步的总的时间是不是能被更小的值更新,即如果出现时间更短的时候再让这个值重新入队,所以和优先队列没有关系。不需要时间短先用,时间短的也可能被时间长的更新,只需要dist[a][b]== -1 || t+1<dist[a][b]如果这个成立就更新入队
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;

int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
char g[100][100];
int dist[100][100];
int r1,c1,r2,c2,n,m;

struct nod
{
    int w,x,y;
};

bool check(int x,int y)
{
    if(x>=0&&x<n&&y>=0&&y<m)
        return 1;
    return 0;
}

void bfs()
{
    memset(dist,-1,sizeof dist);
    queue<nod>q;
    q.push({0,r1,c1});
    dist[r1][c1]=0;
    
    while(q.size())
    {
        auto [t,x,y]=q.front();q.pop();
        //不能在这里输出dist[a][b],因为可能会更新他
        for(int i=0;i<4;i++)
        {
            int a = x+dx[i],b=y+dy[i];
            if(g[a][b]=='.')
            {
                if(check(a,b)&&(dist[a][b]==-1||t+1<dist[a][b]))
                //这里一定要t+1<dist[a][b],因为如果跳过去之前和走过去之前
                //时间是一样的,但挑过去在队头,那时间就变成t+2,但其实是t+1
                {
                    dist[a][b] = t+1;
                    q.push({t+1,a,b});
                }
            }
            else 
            {
                while(g[a][b]=='#'&&check(a,b))
                {
                    a+=dx[i],b+=dy[i];
                }
                if(check(a,b)&&(dist[a][b]==-1||t+1<dist[a][b]))
                {
                    dist[a][b]=t+2;
                    q.push({t+2,a,b});
                }
            }
        }
            
    }
    cout<<dist[r2][c2]<<endl;
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)
        cin>>g[i];
    scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
    
    bfs();

    return 0;
}

全部评论
Orz
点赞 回复 分享
发布于 2024-11-08 21:24 浙江

相关推荐

06-13 17:33
门头沟学院 Java
顺序不记了,大致顺序是这样的,有的相同知识点写分开了1.基本数据类型2.基本数据类型和包装类型的区别3.==和equals区别4.ArrayList与LinkedList区别5.hashmap底层原理,put操作时会发生什么6.说出几种树型数据结构7.B树和B+树区别8.jvm加载类机制9.线程池核心参数10.创建线程池的几种方式11.callable与runnable区别12.线程池怎么回收线程13.redis三剑客14.布隆过滤器原理,不要背八股,说说真正使用时遇到了问题没有(我说没有,不知道该怎么回答了)15.堆的内存结构16.自己在写项目时有没有遇见过oom,如何处理,不要背八股,根据真实经验,我说不会17.redis死锁怎么办,watchdog机制如何发现是否锁过期18.如何避免redis红锁19.一个表性别与年龄如何加索引20.自己的项目的QPS怎么测的,有没有真正遇到大数量表21.说一说泛型22.springboot自动装配原理23.springmvc与springboot区别24.aop使用过嘛?动态代理与静态代理区别25.spring循环依赖怎么解决26.你说用过es,es如何分片,怎么存的数据,1000万条数据怎么写入库中27.你说用limit,那么在数据量大之后,如何优化28.rabbitmq如何批次发送,批量读取,答了延迟队列和线程池,都不对29.计网知不知道smtp协议,不知道写了对不对,完全听懵了30.springcloud知道嘛?只是了解反问1.做什么的?短信服务,信息量能到千万级2.对我的建议,基础不错,但是不要只背八股,多去实际开发中理解。面试官人不错,虽然没露脸,但是中间会引导我回答问题,不会的也只是说对我要求没那么高。面完问我在济宁生活有没有困难,最快什么时候到,让人事给我聊薪资了。下午人事打电话,问我27届的会不会跑路,还在想办法如何使我不跑路,不想扣我薪资等。之后我再联系吧,还挺想去的😭,我真不跑路哥😢附一张河科大幽默大专图,科大就是大专罢了
查看30道真题和解析
点赞 评论 收藏
分享
评论
4
收藏
分享

创作者周榜

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