BFS解决八数码问题-java

本文主要通过BFS广度优先搜索来解决八数码问题。

文章目录

前言

一、八数码

二、算法思路

1.思路模拟

2.实现思路

三、代码

1.代码如下:

2.读入数据

3.代码运行结果

总结


前言

本文主要通过BFS广度优先搜索来解决八数码问题。


提示:以下是本篇文章正文内容,下面案例可供参考

一、八数码

在一个 3×3的网格中,1∼8 这 8 个数字和一个 x 恰好不重不漏地分布在这 3×3 的网格中。

例如:

1 2 3
x 4 6
7 5 8

我们可以通过x与它的上下左右四个方向之一的数字进行交换作来让最后的网格变成如下正确排列:

1 2 3
4 5 6
7 8 x

 上述过程的具体交换如下:

1 2 3   1 2 3   1 2 3   1 2 3
x 4 6   4 x 6   4 5 6   4 5 6
7 5 8   7 5 8   7 x 8   7 8 x

现在,给你一个初始网格,请你求出得到正确排列至少需要进行多少次交换。

输入格式:

输入占一行,将 3×3的初始网格描绘出来。

 上述输入例如:1 2 3 x 4 6 7 5 8

输出格式:

输出占一行,包含一个整数,表示最少交换次数。

如果不存在解决方案,则输出 −1。

二、算法思路

1.思路模拟

图1.1思路模拟 

如图1.1所示,x有四种交换方式,那我们可以把最后的结果抽象为x在当前位置,走各种情况且最短距离到达最右下角的时候,所得到的最后的序列与正确序列是否相同,相同了输出此时的交换次数即最小交换次数,如果不同,直接打印-1,说明得不到正确的序列。

 x的移动方式我们可以用两个一维数组分别x和y的变化量即dx,dy 

dx = (-1,1,0,0)

 dy = (0,0,-1,1)

 四个变化量分别表示上、下、左、右横纵坐标的变化量。

因为这道题是直接输入了一行,我们可以用字符串start来存储整个序列。

图1.2下标转换 

如图1.2所示矩阵中横坐标x:下标 / 3;矩阵中纵坐标y:下标 % 3

因此当我们用BFS进行时,每一个点的状态我们可以直接用字符串类型的队列queue<String>来存储即可,并且每一个从初始起点到该状态的步数即交换次数用一个键为String、值为Integer的集合dist来存储。   

2.实现思路

我们先向队列中添加起始状态strat,然后向dist中添加起始状态的交换次数0,然后进行循环,当队列非空时,弹出队头元素即此时的状态字符串pool,如果此时poll跟最后状态“12345678x”字符串end相同时说明我们此时已经完成了正确序列的交换并且我们上下左右操作每一次都是在原状态的操作次数加1,此时dist.get(end)就是我们的最小交换次数。当pool跟end不匹配时,那么我们通过图1.2来得到在3*3棋盘中的横纵坐标x、y,然后通过for循环来得到上下左右四个状态对应变化后的横纵坐标a、b。当然我们得判断a、b是否在棋盘中越界,并且我们得上下左右移动完成交换后的新字符串是否在dist集合中出现过,dist.get(str)不为空就说明我们已经走过这个状态,就不必再走了;为空就说明这个状态我们未交换过,那么我们就将新状态压入队列,然后得到原先字符串状态的交换次数即dist.get(pool),然后再把新状态和对应的交换次数(原状态交换次数+1)即dist.map(str,dist.get(pool)+1)放入集合dist。当我们队列为空且最后一个状态仍与结尾状态不一样说明无法得到最后的正确序列,返回-1即可。

三、代码

1.代码如下:


import java.io.*;
import java.util.*;
public class Main {static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//初始字符串static String start;public static void main(String[] args) {Scanner sc = new Scanner(br);//把输入的一行中的空格全部替换没了start = sc.nextLine().replaceAll("\\s+","");pw.println(bfs());pw.flush();}public static int bfs(){String end = "12345678x";Queue<String> queue = new LinkedList<>();Map<String,Integer>dist = new HashMap<>();queue.add(start);dist.put(start,0);//上下左右int[] dx = {-1,1,0,0};int[] dy = {0,0,-1,1};while (!queue.isEmpty()){//取出队头元素String pool = queue.poll();if(pool.equals(end)){return dist.get(end);}//找到x的下标int k = pool.indexOf('x');int x = k / 3;int y = k % 3;//表示上下左右四个状态for(int i = 0;i < 4;i++){//变化后的x坐标int a = x + dx[i];//变化后的y的坐标int b = y + dy[i];//判断下标是否在矩阵中越界if(a >= 0 && a < 3 && b >= 0 && b < 3){char[] arr = pool.toCharArray();//将x和此时变化后的字符进行交换swap(arr,k,a * 3 + b);//将字符数组转换成字符串String str = new String(arr);//说明此时的状态是未走过的if(dist.get(str) == null){//将新状态添加进队列queue.add(str);//走到新状态那就原本的状态对应的字符串交换次数+1dist.put(str, dist.get(pool) + 1);}}}}//当我们走完之后字符串与目标序列不同说明根本交换不到正确序列,返回结果-1return -1;}//地址传递 交换字符public static void swap(char[] arr,int a,int b){char temp = arr[a];arr[a] = arr[b];arr[b] = temp;}
}

2.读入数据

2  3  4  1  5  x  7  6  8 

3.代码运行结果

19

总结

上述也是通过BFS来解决最短路的问题,我们只要分清楚各个状态如何变化和存储,知道一个点是从哪个点抽象变化过来的,就可以解决这一类问题。

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

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

相关文章

7.2K star!一个完全免费,可以本地部署的 AI 搜索聚合器。新手可尝试

原文链接&#xff1a;7.2K star&#xff01;一个完全免费&#xff0c;可以本地部署的 AI 搜索聚合器。新手可尝试 ChatGPT 刚上线的时候我用的很少&#xff0c;还是习惯用 Google。主要还是因为不信任&#xff0c;怕它对我胡说八道。 慢慢的&#xff0c;也没有一个明确的时间…

工业4.0!智能工厂的智能物流系统应用

agv 智能物流系统通常指连接生产设备之间、车间之间以及车间与仓库之间的物流搬运系统。 为实现智能物流系统搭建&#xff0c;应该在尊重原有印刷生产工艺与合理生产布局基础上&#xff0c;通过应用新的生产智能化装备来实现协调车间的整体调度。 agv智能工厂 在现代化的物料搬…

java后端项目:视积分抽奖平台

一、项目背景: 本次抽奖系统实现是在视频中内置一个线上活动抽奖系统,奖品是在一个时间段区间内均匀发布,用户可以在这个时间段内参与抽奖。 二、项目架构 活动抽奖平台采用微服务架构来完成,在功能上实现拆分为用户、网关、以及抽奖微服务,其中用户、网关是后台项目通…

智能家居—ESP32开发环境搭建

相关文章 毕业设计——基于ESP32的智能家居系统(语音识别、APP控制) 智能家居—ESP32开发环境搭建 一、下载安装二、验证三、资料获取 一、下载安装 下载安装 vscode 安装插件 创建工程 二、验证 写一个简单的函数来验证一下功能 void setup() {// put your setup c…

常见UI组件(二)

一、文本输入 1.1 概述 TextInput为文本输入组件&#xff0c;用于接收用户输入的文本内容 1.2 参数 Entry Component struct Index {build() {Column({space : 50}) {TextInput({placeholder:请输入用户名}).width(70%)TextInput({text:当前内容}).width(70%)}.width(100%).…

光学雨量计:高精度测量降水量的理想解决方案

光学雨量计&#xff1a;高精度测量降水量的理想解决方案 河北稳控科技光学雨量计是一种高精度测量降水量的理想解决方案。它利用光学原理&#xff0c;通过光束的衰减来测量降雨强度和累积降水量。相比传统的雨量计&#xff0c;光学雨量计具有更高的精度和可靠性&#xff0c;成…

科研基础与工具(论文写作)

免责申明&#xff1a; 本文内容只是学习笔记&#xff0c;不代表个人观点&#xff0c;希望各位看官自行甄别 参考文献 科研基础与工具&#xff08;YouTube&#xff09; 学术写作句型 Academic Phrase bank 曼彻斯特大学维护的一个网站 写论文的时候&#xff0c;不不知道怎么…

IDEA开启自动导包,自动删包

找到file----------->Settings选项 找到Editor-------->General------------>Auto Import选项 勾选两个选项&#xff0c;在点击Apply,在点击ok 最后就ok了

入门指南:从零开始学习ReactJS

&#x1f482; 个人网站:【 摸鱼游戏】【神级代码资源网站】【工具大全】&#x1f91f; 一站式轻松构建小程序、Web网站、移动应用&#xff1a;&#x1f449;注册地址&#x1f91f; 基于Web端打造的&#xff1a;&#x1f449;轻量化工具创作平台&#x1f485; 想寻找共同学习交…

2024三掌柜赠书活动第二十四期:containerd原理剖析与实战

目录 前言 Containerd的架构 Containerd的工作流程 Containerd的实战演示 关于《containerd原理剖析与实战》 编辑推荐 内容简介 作者简介 图书目录 书中前言/序言 《containerd原理剖析与实战》全书速览 结束语 前言 作为开发者&#xff0c;对于编程语言并不陌生&…

Win10下VS2015无法添加任何文件,提示未能加载文件或程序集“Microsoft.VisualStudio.JSLS...

错误&#xff1a;未能加载文件或程序集“Microsoft.VisualStudio.JSLS, Version14.0.0.0, Cultureneutral, PublicKeyTokenb03f5f7f11d50a3a”或它的某一个依赖项。系统找不到指定的文件。 解决&#xff1a; 1. 管理员身份打开cmd 2. cd C:\Program Files (x86)\Microsoft Vis…

CommunityToolkit.Mvvm笔记---RelayCommand

RelayCommand 和 RelayCommand<T> 是 ICommand 实现&#xff0c;这些实现可向视图公开方法或委托。 这些类型充当在 viewmodel 和 UI 元素之间绑定命令的方法。 平台API&#xff1a;RelayCommand、RelayCommand<T>、IRelayCommand、IRelayCommand<T> 工作原理…

input的type=‘radio‘设置只读属性颜色为灰色,如何修改

目录 1.设置input和label的样式为不可点击。 2.设置input的readonly属性。 3.若想变回可修改&#xff0c;用js实现 4.如何自定义radio的颜色。 5.完整代码 input的单选框有时候需要实现只读&#xff0c;两个办法&#xff0c;一个disabled&#xff0c;一个是readonly. 但d…

【InternLM】Lagent智能体应用搭建

1. Lagent和AgentLego 1.1 Lagent Lagent 是一个开源的 LLM 智能体框架&#xff0c;允许使用者快速将一个大语言模型转换成智能体&#xff0c;并提供一些典型工具来激发大语言模型的潜能。Lagent 框架图如下&#xff1a; Lagent 包含三个主要模块&#xff1a;agents&#xf…

ubuntu18.04安装F4PGA教程

环境搭建教程&#xff1a; f4pga-arch-defs/xilinx/xc7 at main f4pga/f4pga-arch-defs GitHub git clone https://github.com/SymbiFlow/f4pga-arch-defs.git cd f4pga-arch-defs make env cd build 主要是make env&#xff0c;会下载很多东西&#xff0c;然后生成很多描…

38. 【Android教程】Handler 消息传递机制

跑在主线程&#xff08;即UI线程&#xff09;当中的&#xff0c;而且所有的 UI 刷新以及输入处理必须在主线程中执行。这样一旦任务多了就会阻塞 UI 线程导致画面卡顿&#xff0c;从而严重影响性能&#xff0c;所以正确的做法是将耗时的操作单独放在子线程中与 UI 线程隔离&…

本地代码配置多个远程仓库进行推送

Git配置多个远程仓库 问题解决办法新增远程地址推送 问题 目前一个项目正在一个仓库中存储&#xff0c;需要新增一个仓库&#xff0c;实现能同时推送到两个仓库中&#xff0c;比如一个项目同时维护在github和gitee上。 解决办法 新增远程地址 直接在本地项目根目录下输入: …

玩原神玩的!30本提升你视野、眼界和格局的好书不如你挑的一本适合自己的书!——早读(逆天打工人爬取热门微信文章解读)

许久不见&#xff0c;雨天坐公车&#xff0c;别是一番滋味在心头 引言Python 代码第一篇 洞见 人民日报推荐&#xff1a;30本提升你视野、眼界和格局的好书第二篇 人民日报 来了&#xff01;新闻早班车要闻社会政策 结尾 不要着急 最好的总会在最不经意的时候出现 意外的六分钟…

Linux系统中Nginx的使用

Nginx是一款开源的高性能、高可靠性的Web服务器和反向代理服务器。它在Linux系统中得到了广泛的应用&#xff0c;被用于构建高性能的Web应用和提供反向代理服务。下面将介绍Nginx在Linux系统中的使用以及一些常见的应用案例。 一、Nginx的安装和配置 安装Nginx 在Linux系统中…