AcWing——方格迷宫(有点不一样的迷宫问题)

news2024/11/17 13:45:08

4943. 方格迷宫 - AcWing题库

 1、题目

给定一个 n 行 m 列的方格矩阵。

行从上到下依次编号为 1∼n,列从左到右依次编号为 1∼m。

第 i 行第 j 列的方格表示为 (i,j)。

矩阵中的方格要么是空地(用 . 表示),要么是陷阱(用 # 表示)。

初始时,你位于方格 (x₁,y₁),你需要前往方格 (x₂,y₂)。

每次移动,你可以任选上、下、左、右四个方向之一,并沿该方向移动 1∼k 步。

从一个方格移动至相邻方格视为一步。

但是,你要保证在你的移动过程中不能走出矩阵,也不能进入陷阱方格。

请你计算从方格 (x₁,y₁) 移动至方格 (x₂,y₂),所需要的最少移动次数

保证方格 (x₁,y₁) 和方格 (x₂,y₂) 都是空地。

方格 (x₁,y₁) 和方格 (x₂,y₂) 可能是同一个方格。

注意:注意区分本题中移动次数与移动步数的区别。

输入格式

第一行包含三个整数 n,m,k。

接下来 n 行,每行包含 m 个字符,其中第 i 行第 j 个字符,要么是 .,表示方格 (i,j) 是空地;要么是 #,表示方格 (i,j) 是陷阱。

最后一行包含四个整数 x₁,y₁,x₂,y₂。

输出格式

一个整数,表示所需要的最少移动次数

如果无法从方格 (x₁,y₁) 移动至方格 (x₂,y₂),则输出 -1

数据范围

前 6 个测试点满足 1≤n,m≤10。
所有测试点满足 1≤n,m,k≤1000,1≤x₁,x₂≤n,1≤y₂,y₂≤m。

输入样例1:

3 4 4
....
###.
....
1 1 3 1

输出样例1:

3

输入样例2:

3 4 1
....
###.
....
1 1 3 1

输出样例2:

8

输入样例3:

2 2 1
.#
#.
1 1 2 2

输出样例3:

-1

2、题目解读

走迷宫_牛客题霸_牛客网 (nowcoder.com)

牛客网这题就是正常,普通求解最短步数的迷宫问题,而这题添加了一个条件:每次移动你可以任选上、下、左、右四个方向之一,并沿该方向移动 1∼k 步这称为 一次移动。

我们使用BFS去正常解答这道题目时间复杂度为O(nmk)最大为10⁹,这就会超时。


import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Main {
    static int n,m,k,x1,x2,y1,y2;
    static char[][] ch;
    static int[][] move ={{0,1},{0,-1},{1,0},{-1,0}};//四个方向,偏移量
    static int inf=0x3f3f3f3f;//初始化移动次数
    static int[][] ans;//记录移动次数
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        n=sc.nextInt();
        m=sc.nextInt();
        k=sc.nextInt();
        ch =new char[n][];
        ans =new int[n][m];
        for(int i=0;i<n;i++){
            ch[i]=sc.next().toCharArray();
        }
        x1=sc.nextInt()-1;
        y1=sc.nextInt()-1;
        x2=sc.nextInt()-1;
        y2=sc.nextInt()-1;
        for(int i=0;i<n;i++){//初始化移动次数
            Arrays.fill(ans[i],inf);
        }
        System.out.println(bfs());
    }
    public static int bfs(){
        ans[x1][y1]=0;
        Queue<int[]> q=new LinkedList<>();
        q.add(new int[]{x1,y1,0});
        while(!q.isEmpty()){
            int[] a =q.poll();
            for(int[] mo :move){//四个方向
                for(int i=1;i<=k;i++){//移动一次:移动1-k步
                    int x=a[0]+mo[0]*i,y=a[1]+mo[1]*i;
                    if(x<0||x==n||y<0||y==m||ch[x][y]=='#'){//不能出去,不能跨越陷阱
                        break;
                    }
                    if(ans[x][y]>a[2]+1){//修改移动次数
                        ans[x][y]=a[2]+1;
                        q.add(new int[]{x,y,a[2]+1});
                    }
                }
            }
        }
        //走完整个地图,判断目的地是否可以走到
        return ans[x2][y2]==inf?-1:ans[x2][y2];
    }
}

我们需要优化代码,看下面图:

 

所以我们应该 更新到格子发现不是最优,就应该停止。这样时间复杂度就退化到了O(nm)

需要在判断条件处新加:ans[x][y]<a[2]+1

3、代码


import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Main {
    static int n,m,k,x1,x2,y1,y2;
    static char[][] ch;
    static int[][] move ={{0,1},{0,-1},{1,0},{-1,0}};//四个方向,偏移量
    static int inf=0x3f3f3f3f;//初始化移动次数
    static int[][] ans;//记录移动次数
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        n=sc.nextInt();
        m=sc.nextInt();
        k=sc.nextInt();
        ch =new char[n][];
        ans =new int[n][m];
        for(int i=0;i<n;i++){
            ch[i]=sc.next().toCharArray();
        }
        x1=sc.nextInt()-1;
        y1=sc.nextInt()-1;
        x2=sc.nextInt()-1;
        y2=sc.nextInt()-1;
        for(int i=0;i<n;i++){//初始化移动次数
            Arrays.fill(ans[i],inf);
        }
        System.out.println(bfs());
    }
    public static int bfs(){
        ans[x1][y1]=0;
        Queue<int[]> q=new LinkedList<>();
        q.add(new int[]{x1,y1,0});
        while(!q.isEmpty()){
            int[] a =q.poll();
            for(int[] mo :move){//四个方向
                for(int i=1;i<=k;i++){//移动一次:移动1-k步
                    int x=a[0]+mo[0]*i,y=a[1]+mo[1]*i;
                    //不能出去,不能跨越陷阱,还有更新到格子发现不是最优,就应该停止
                    if(x<0||x==n||y<0||y==m||ch[x][y]=='#'||ans[x][y]<a[2]+1){
                        break;
                    }
                    if(ans[x][y]>a[2]+1){//修改移动次数
                        ans[x][y]=a[2]+1;
                        q.add(new int[]{x,y,a[2]+1});
                    }
                }
            }
        }
        //走完整个地图,判断目的地是否可以走到
        return ans[x2][y2]==inf?-1:ans[x2][y2];
    }
}

 

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

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

相关文章

前后端身份认证:session身份认证,JWT认证

文章目录 前后端身份认证1、概述2、不同开发模式下的身份认证3、关于HTTP协议的无状态性4、Cookie4.1 介绍4.2 cookie特点4.3 cookie分类4.4 Cookie在session身份认证中的作用4.5 Cookie不具有安全性 5、Session认证5.1 Session认证过程5.2 Session认证原理图5.3 Session认证的…

【Linux】多线程 --- 线程概念 控制 封装

从前种种&#xff0c;譬如昨日死。从后种种&#xff0c;往如今日生。 文章目录 一、线程概念1.重新理解用户级页表1.1 进程资源如何进行分配呢&#xff1f;&#xff08;地址空间页表&#xff09;1.2 虚拟地址如何转换到物理地址&#xff1f;&#xff08;页目录页表项&#xff0…

11 KVM虚拟机配置-配置虚拟设备(存储)

11 KVM虚拟机配置-配置虚拟设备(存储) 文章目录 11 KVM虚拟机配置-配置虚拟设备(存储)11.1 存储设备概述11.2 存储设备元素介绍11.3 存储设备配置示例 11.1 存储设备概述 虚拟机XML配置文件使用devices元素配置虚拟设备&#xff0c;包括存储设备、网络设备、总线、鼠标等。 X…

【LeetCode】494. 目标和

494. 目标和 思路 首先&#xff0c;将这道题想成 0-1背包问题&#xff0c;我们最终要输出的结果是最多的方法数&#xff0c;因此 dp 数组需要记录具体的方法数。 状态定义 按照 0-1 背包问题的套路&#xff0c;我们将状态定义为 &#xff1a;dp[i][j] &#xff0c;表示「前 …

YOLOv5测距+碰撞检测

YOLOv5测距碰撞检测 1. 相关配置2. 测距原理3. 标定和测距4. 碰撞检测4.1 相关代码4.2 主代码 5. 实验效果 相关链接 1. YOLOV5 单目测距&#xff08;python&#xff09; 2. YOLOV7 单目测距&#xff08;python&#xff09; 3. 具体实现效果已在Bilibili发布&#xff0c;点击…

string的介绍

string是c中表示字符串的字符串类&#xff0c;要使用需要包头文件&#xff1a;#include<string> 先了解一下string的一些信息 string看起来是一个类&#xff0c;但实际上是typedef的模板。 在cplusplus.com网站上&#xff0c;string的相关信息 模板的实例化结果有以下几个…

【unity小创意】相机的正反操作实现场景的二维跳跃

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…

Spring的第十二阶段(01):Spring实现AOP的简单使用

1、使用Spring实现AOP简单切面编程 需要导入工程的jar包 Spring的核心包 spring-beans-4.0.0.RELEASE.jar spring-context-4.0.0.RELEASE.jar spring-core-4.0.0.RELEASE.jar spring-expression-4.0.0.RELEASE.jarSpring的测试包 spring-test-4.0.0.RELEASE.jarSpring日记相…

【网络安全】这套面试题,让你提前预判面试官的预判!

最近这个帖子的点赞和收藏变高起来了&#xff0c;许多小伙伴在问我安全大厂的面试题没有&#xff0c;我准备利用一些时间把这套面试宝典整理一下&#xff01; 今天有同学拿着他准备的面试问题清单给我看&#xff0c;看还有没有遗漏的&#xff0c;我看了下&#xff0c;觉得还是…

Spring-Bean管理-注解

组件注册 Component/Controller/Service/Repostory :注册自定义组件到容器中 加上约定的注解。 在Configuration注解的类中配置包扫描器 ComponentScan(vlaue "cn.shaoxiongdu") Configuration: 标注配置类 Scope &#xff1a; 配置是否为单实例 prototype: 多实…

JVM与GC

Java:跨平台的语言 write once, run anywhere JVM&#xff1a;跨语言的平台 Java虚拟机根本不关心运行在其内部的程序到底是使用何种编程语言编写的&#xff0c;它只关心“字节码”文件。 Java不是最强大的语言&#xff0c;但是JVM是最强大的虚拟机。 JVM的整体结构 这个架构…

Java基础学习(12)

Java基础学习 一、不可变集合二、Stream流2.1 Stream流数据添加2.2 Stream流的中间方法2.3 Stream终结方法 三、 方法引用3.1 方法引用的基本概念3.2 方法引用的分类3.2.1 引用静态方法 3.2.2 引用成员方法3.2.3 引用构造方法3.2.4 使用类名引用成员方法3.2.5 引用数组的构造方…

PyQt5 基础篇(一)-- 安装与环境配置

1 PyQt5 图形界面开发工具 Qt 库是跨平台的 C 库的集合&#xff0c;是最强大的 GUI 库之一&#xff0c;可以实现高级 API 来访问桌面和移动系统的各种服务。PyQt5 是一套 Python 绑定 Digia QT5 应用的框架。PyQt5 实现了一个 Python模块集&#xff0c;有 620 个类&#xff0c;…

MATLAB 点云非均匀体素下采样 (8)

MATLAB 点云非均匀体素下采样的不同参数效果测试 (8) 一、实现效果二、算法介绍三、函数说明3.1 函数3.2 参数四、实现代码(详细注释!)五、与固定步长采样法比较5.1 代码5.2 效果一、实现效果 不同参数调整下的非均匀体素下采样结果如下图所示,后续代码复制黏贴即可: 可…

入职6个月,被裁了...

我跟大多数人不大一样&#xff0c;从来没有说要等公司主动裁员拿补偿&#xff0c;我看自己没有什么价值或者是公司不行了&#xff0c;我都会主动离职。但是这次也太突然了。公司很大已上市&#xff0c;并不是不行了&#xff0c;总结原因就是&#xff0c;一是领导无能&#xff0…

【STM32CubeMX】F103ADC获取

前言 本文记录了我学习STM32CubeMX的过程&#xff0c;方便以后回忆。我们使用的开发板是基于STM32F103C6T6的。本章记录了基本的ADC值的获取流程&#xff0c;只单纯地记录了ADC端口的配置&#xff0c;没有加配像串口之类的调试&#xff0c;以简化流程。下面的流程是使用串口调试…

版本控制系统Git - 配置与基本使用

Git 1 Git简介1 Git概述2 Git的作用2.1 项目版本管理2.2 多人协同开发2.3 Git 的结构2.4 Git的工作原理 2 Git安装1 下载Git2 安装Git3 配置环境变量4 测试git是否安装成功5 安装git桌面工具(可以不安装) 3 Git基本操作1 设置Git用户2 新建仓库3 查看仓库状态4 添加到暂存文件5…

MATLAB 点云重复点去除(7)

MATLAB 点云重复点去除 (7) 一、实现效果二、算法介绍三、函数说明3.1 函数3.2 参数四、具体代码 (注释详细!)一、实现效果 效果上看不出来,但实际上左边的点云是右边的两倍 二、算法介绍 重复点的去除,是点云处理中常用的预处理方法,因为重复点的存在有时候会严重干…

C++系列四:数组

数组 1. 数组定义与初始化2. 多维数组3. 字符数组4. 总结 1. 数组定义与初始化 定义数组时需要指定数组的类型和大小&#xff1a; int myArray[10];上述代码定义了一个包含 10 个整数的数组。这些整数的下标从 0 开始&#xff0c;并以 1 个单位递增。 C 允许在定义数组时对其…

设计模式——装饰者模式(继承和接口的两种实现方式)

是什么&#xff1f; 场景案例&#xff1a;想必大家都吃过手抓饼吧&#xff0c;我们在点手抓饼的时候可以选择加培根、鸡蛋、火腿、肉松等等这些配菜&#xff0c;当然这些配菜的价格都不一样&#xff0c;那么计算总价就比较麻烦&#xff1b; 装饰者模式就是指在不改变现有对象…