【BFS】华子20230506笔试第三题(动态迷宫问题)Java实现

news2024/12/24 2:29:39

文章目录

    • 题目链接
    • 思路
    • BFS板子
    • 我的解答

题目链接

塔子哥的codeFun2000:http://101.43.147.120/p/P1251
在这里插入图片描述

测试样例1
输入

3
2
1 0 1 2
2 1 2 0
100 100 100
100 000 100
000 000 001

输出

1

测试样例2
输入

3
2
1 0 2 0
0 1 2 2
000 000 001
010 101 101
110 010 000

输出

5

解释:最快的移动顺序: [2,2] ->[1,2] ->[2,2] ->[2,1] ->[1,1] ->[0,1]

思路

本题属于迷宫类最短路径的问题,首先想到的是BFS,但与常规的迷宫问题不同,该题目中迷宫地图为动态的,障碍物(墙壁)会发生改变,其变化存在周期性(周期为3,对应三个时间点的地图)。且题目中冒险家可选择原地不动,即每次移动有上、下、左、右、原地不动共5种情况。另外,题目中需求解最短时间与常规BFS求解最短路径长度没有本质区别。

综上思考,结合原题,代码思路总结为以下几点:

  • 直接套用BFS板子。
  • 将迷宫存储为动态,用三维邻接矩阵存储(第一维为时间);同时地图中还有不随时间改变的陷阱,即存在动态障碍静态障碍
  • 每次移动共有5种情况。
  • 在常规BFS中的用于记录(x,y)是否走过的boolearn visited数组,在本题中改为三维,即对应三个时间点的某个位置(x,y)是否走过。
  • BFS的队列中存储每个点及到达该点的时间,每个点为(x,y,t)。
  • 因地图以三个单位时间循环,也就说如果地图中的所有可达点对应的三个时刻均被走过,则题目无解。

BFS板子

BFS模板:While循环+队列

分支限界法(BFS、广度优先搜索):每一个活结点只有一次机会成为扩展结点,一旦活结点成为了扩展结点,就一次性产生其所有的儿子结点。其目标为尽快找出满足约束条件的一个解。

// 计算从起点 start 到终点 target 的最近距离
int BFS(Node start, Node target) {
    Queue<Node> q; // 核心数据结构
    Set<Node> visited; // 用于记录某个点是否走过,避免走回头路,在二维矩阵迷宫常用boolean[][]记录某个点x,y是否走过
    
    q.offer(start); // 将起点加入队列
    visited.add(start);
    int step = 0; // 记录扩散的步数

    while (q not empty) {
        int sz = q.size();
        /* 将当前队列中的所有节点向四周扩散 */
        for (int i = 0; i < sz; i++) { 
            Node cur = q.poll();
            /* 划重点:这里判断是否到达终点 */
            if (cur is target)
                return step;
            /* 将 cur 的相邻节点加入队列 */
            for (Node x : cur.adj()) { // 一旦活结点成为了扩展结点,就一次性产生其所有的儿子结点。
                if (x not in visited) {
                    q.offer(x);
                    visited.add(x);
                }
            }
        }
        /* 划重点:更新步数在这里 */
        step++;
    }
}

以上模板来自东哥总结,地址:labuladong

我的解答

import java.util.*;

/**
 * @program: 
 * @ClassName Main
 * @description: 
 * @author: wangzp
 * @create: 2023-05-06
 * @Version 1.0x
 **/
public class Main {

    static int N;
    static int K;

    static Set<String> guaiwuset = new HashSet<>(); // 用于存储地图中的静态障碍

    static int row1,col1; // 公主(宝藏)
    static int row2,col2; // 王子(冒险家)

    static Queue<int[]> queue; //BFS的队列中存储每个点及到达该点的时间,每个点为(x,y,t)

    static int[][][] graph;// 三维的链接矩阵矩阵存储动态地图

    public static void main(String[] args) {
        // 1.处理输入
        Scanner scanner = new Scanner(System.in);
        N = scanner.nextInt();
        K = scanner.nextInt();
        graph = new int[3][N][N]; // 0 1 2 共三个时间点的地图
        for (int i = 0; i < K; i++) {
            int x = scanner.nextInt();
            int y = scanner.nextInt();
            guaiwuset.add(""+x+"-"+y);
        }
        row1 = scanner.nextInt();
        col1 = scanner.nextInt();
        row2 = scanner.nextInt();
        col2 = scanner.nextInt();

        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                String str = scanner.next();
                graph[0][i][j] = Integer.valueOf(Character.toString(str.charAt(0)));
                graph[1][i][j] = Integer.valueOf(Character.toString(str.charAt(1)));
                graph[2][i][j] = Integer.valueOf(Character.toString(str.charAt(2)));
            }
        }
        // 2.解答开始
        queue = new LinkedList<>(); // BFS的队列
        boolean[][][] visitedSum = new boolean[N][N][3]; // 记录某个时间点的某个位置是否`走过`

        queue.add(new int[]{row2,col2,0});  // 将初始节点放入队列
        visitedSum[row2][col2][0] = true;   // 将初始节点的0时刻标记为`走过`

        int time = 0;// 记录时间
        while (!queue.isEmpty()){
            int q_size = queue.size();

            for (int i = 0; i < q_size; i++) {
                int[] cur = queue.poll();
                int curx = cur[0];
                int cury = cur[1];
                int curtime = cur[2];
                //System.out.println("x="+curx+" y="+cury+" curtime="+curtime);

                if(curx == row1 && cury == col1){ // 找到最终目标,直接返回答案
                    System.out.println(curtime);
                    return;
                }
                int[][] fangxiang = new int[][]{{0,-1},{0,1},{-1,0},{1,0},{0,0}}; // 上下左右及原地不动5种选择
                for(int[] f:fangxiang){
                    int newx = curx + f[0];
                    int newy = cury + f[1];
                    int newtime = curtime+1;
                    // 判断越界
                    if(newx<0||newx>=N||newy>=N||newy<0)continue;
                    // 判断静态障碍
                    if(guaiwuset.contains(""+newx+"-"+newy)){ // 有怪兽(陷阱)
                        continue;
                    }
                    // 判断动态障碍
                    if(graph[newtime%3][newx][newy]==1){ // 下个节点有障碍
                        continue;
                    }
                    // 判断是否走过
                    if(visitedSum[newx][newy][newtime%3] == true){
                        continue;
                    }
                    queue.offer(new int[]{newx,newy,newtime});
                    visitedSum[newx][newy][newtime%3] = true;
                }
            }
        }
        System.out.println("-1");
    }
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/531856.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在docker容器中启动docker服务并实现构建多平台镜像的能力

在docker容器中启动docker服务并实现构建多平台镜像的能力 背景 在容器中运行docker&#xff0c;是devops中无法避免的场景&#xff0c;通常被应用于提供统一的镜像构建工具&#xff0c;出于安全考虑&#xff0c;不适合将主机的docker进程暴露给公司的内部人员使用&#xff0…

SpringCloud alibaba微服务b2b2c电子商务平台

1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务、系统服务、中间件服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot2、My…

飞书开发流程

1、进入飞书并创建一个应用 链接: 创建应用 创建应用成功后需要审核通过&#xff0c;如果你拥有管理权限则可以自己进入管理后台通过审核&#xff0c;否则需要联系管理员通过审核 2、进入开发者后台 链接: 发者后台 3、在该调试平台上测试 以这个订阅审批事件为例 这一步…

DHCP协议简单配置

实验原理 网络中主机需要与外界进行通信时,需要配置自己的IP地址、网关地址、DNS服务器等网络参数信息。手工在每台主机上配置维护成本高,容易出错,而且不利于管理员统一维护。 通过DHCP地址自动配置协议,使终端设备能自动获取地址,实现即插即用且IP地址统一由服务器管理…

springboot+java充电桩充电额维修管理系统

项目介绍 Spring Boot 是 Spring 家族中的一个全新的框架&#xff0c;它用来简化Spring应用程序的创建和开发过程。也可以说 Spring Boot 能简化我们之前采用SSM&#xff08;Spring MVC Spring MyBatis &#xff09;框架进行开发的过程。 系统基于B/S即所谓浏览器/服务器模式…

STM32 学习笔记_9 定时器中断:编码器接口模式

TIM编码器接口 之前我们处理旋转编码器&#xff0c;是转一下中断一次&#xff0c;挺消耗资源的。 我们可以利用TIM的编码器功能&#xff0c;隔一段时间取一下旋转器值使得cnt或–&#xff0c;以此判断旋转位置以及计算速度&#xff0c;相比中断节约资源。相当于外接了一个有方…

Kubernetes那点事儿——暴露服务之Service

Kubernetes那点事儿——暴露服务之Service 前言一、Service二、Service与Pod关系三、Service常用类型ClusterIPNodePortLoadBalancer 四、Service代理模式IptablesIPVS修改代理模式 前言 K8s中&#xff0c;我们将应用跑在Pod里。多数情况下是一组Pod&#xff0c;用户如何访问这…

凌恩生物美文分享 | 提升科研有一套 | 宏基因组磷循环分析又出新!

磷是包括微生物在内的所有生命体中不可缺少的元素。在生物大分子核酸、高能量化合物ATP、以及生物体内糖代谢的某些中间体中&#xff0c;都有磷的存在。在自然界中&#xff0c;磷的循环包括可溶性无机磷的同化、有机磷的矿化、不溶性磷的溶解等。微生物分解含磷化合物的作用&am…

操作系统面试相关知识

目录 一、简介1、什么是操作系统2、操作系统主要有哪些功能&#xff1f; 二、操作系统结构1、什么是内核&#xff1f;2、什么是用户态和内核态&#xff1f;3、 用户态和内核态是如何切换的&#xff1f; 三、 进程和线程1、并行和并发有什么区别&#xff1f;2、什么是进程上下文…

无线传感器网络的时钟同步估计问题(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 随着无线传感器网络的快速发展,其应用领域也越来越广。在诸多的应用环境中都需要大量已同步的传感器节点通过协同作用执行一个…

Python 中IndexError: list assignment index out of range 错误解决

文章目录 Python IndexError&#xff1a;列表分配索引超出范围修复 Python 中的 IndexError: list assignment index out of range修复 IndexError: list assignment index out of range 使用 append() 函数修复 IndexError: list assignment index out of range 使用 insert()…

怎么把文本翻译成英文?安利三个文本翻译方法

在当今全球化的时代&#xff0c;跨国交流和合作已经成为常态。然而&#xff0c;不同语言之间的沟通障碍经常阻碍着信息传递和理解。为了帮助我们更好地进行国际交流&#xff0c;文本翻译英文软件应运而生。这类软件能够将各种语言的文本迅速准确地翻译成英文&#xff0c;使我们…

【起飞】让你电脑速度快到飞起的一些牛逼的设置整理【电脑卡顿反应慢等问题解决】

对于开发来说电脑的反应速度简直影响了思维的速度&#xff0c;要让电脑速度跟上我们的思维&#xff0c;提高工作效率&#xff0c;早点打卡下班回家陪老婆孩子哈哈 这篇文章主要对windows系统做的一些优化&#xff0c;是真的好用&#xff0c;仿佛在访问静态页面一样&#xff0c;…

超实用!年薪40W的项目经理都在用的6个项目管理软件

项目管理软件是帮助团队进行项目计划、任务分配、进度跟踪和团队协作等方面的工具&#xff0c;已经成为了项目经理必不可少的工具之一。 市面上的项目管理软件有很多&#xff0c;这就来分享一下几款我认为好用的项目管理软件&#xff01; 一、六款好用的项目管理软件 1.简道…

C++开发工具 VTK技术实现三维重建CT医学影像PACS系统

一、信息管理 1、支持对患者、检查项目、申请医生、申请单据、设备等信息进行管理&#xff1b; 2、支持检查病人排队管理功能&#xff1b; 3、支持大屏幕队列显示和语音呼叫&#xff1b; 4、提供预约调整、插队管理和掉队处理等功能&#xff1b; 5、支持急诊申请优先安排。…

美股股指期货重要吗?要注意哪些风险?

美股股指期货是一种以美股股票价格指数作为标的物的金融期货合约。美股股指期货的表现对全球股指市场都有重要的影响力&#xff0c;具体体现在以下方面。 美股股指期货成为全球股指市场风向标 自20世纪70年代起&#xff0c;美国芝加哥商品交易所&#xff08;CME&#xff09;推…

Metasploit基础和实操-渗透测试察打一体(7)

Metasploit 基础包含专业术语,Metasploit 接口介绍,Metasploit 功能介绍 这些是弄渗透测试必须要了解的基础知识,也是0开始玩渗透测试和渗透开发的准备之一。 metasploit命令演示的环境搭建可以参考:https://luozhonghua.blog.csdn.net/article/details/123549917 作者用…

2023.05.14-微调ResNet参加kaggle上猫狗大战比赛打到99%的分类准确率_convert

文章目录 1. 前言2. 下载数据集3. 比赛成绩排名 4. baseline 5. 尝试5.1. 数据归一化&#xff08;98.994%&#xff09;5.2. 使用AdamW优化器&#xff08;98.63%&#xff09;5.3. 使用AdamW优化器SegNet模块&#xff08;95.05%&#xff09; 6. 结语7. 感慨 8. 代码8.1. ResNetNo…

贝尔曼福特算法——负权值单源最短路径

title: 贝尔曼福特算法——负权值单源最短路径 date: 2023-05-16 11:42:26 tags: 数据结构与算法 贝尔曼福特算法——负权值单源最短路径 **问题&#xff1a;**具有负权值非环图的单源最短路径算法 git地址&#xff1a;https://github.com/944613709/HIT-Data-Structures-and-A…

阿里云备案服务码怎么申请?

阿里云备案服务码是什么&#xff1f;ICP备案服务码怎么获取&#xff1f;阿里云备案服务码分为免费和付费两种&#xff0c;申请备案服务码是有限制条件的&#xff0c;需要你的阿里云账号下有可用于申请备案服务码的云产品&#xff0c;如云服务器、建站产品、虚拟主机等&#xff…