(BFS+hash去重)八数码问题

题目:

编号为1~8的8个正方形滑块被摆成3行3列(有一个格子空留)。每次可以把与空格相邻的滑块(有公共边才算相邻)移到空格中,而它原来的位置就称为了新的空格。给定初始局面和目标局面(用0表示空格格),你的任务是计算出最少的移动步数。如果无法达到目标局面,则输-1.

输入:
2 6 4 1 3 7 0 5 8
8 1 5 7 3 6 4 0 2
输出:
31

分析与解:

无权图上的最短路问题可以用BFS求解
涉及到hash内部链表的我抽空再补上(我数据结构还没学好- - |)
先说一下大致思路
这里写图片描述

1.不断移动空格的位置,并将移动的距离进行标记
2.移动过程中会有重复的情况出现,此时利用hash去重
3.一直移动到与目标局面相同,然后输出移动的距离

我写了十分详尽的注释,如下

#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
using namespace std;
typedef int State[9];//定义状态类型 /*
typedef int a[10];
a b[10];//等同与int b[10][10];
*/const int maxstate = 1000000;
State st[maxstate], goal; //状态数组
/*
等价于int st[maxstate][9] 
*/ 
int dist[maxstate];       //距离数组const int dx[] = {-1, 1, 0 , 0};
const int dy[] = {0, 0, -1, 1};const int hashsize = 1000003;
int head[hashsize], n[maxstate];
/*head[]:哈希表 */ void init_lookup_table()
{memset(head, 0, sizeof(head));
}
int Hash(State & s)
{int v = 0;for (int i  = 0; i < 9; i++) v = v * 10 + s[i];//把九个数字合成九位数 return v % hashsize;                    //hash函数值是不超过hash表的大小的非负整数 
}
int try_to_insert(int s)//尾部rear状态 
{int h = Hash(st[s]);//把第rear状态下的st中的元素,转换成一个数 (st[rear][i]->h) int u = head[h];    while (u) {if (memcmp(st[u], st[s], sizeof(st[s])) == 0) return 0;//如果之前访问过该结点,那么直接退出 u = n[u];                                               //顺着链表继续找 }n[s] = head[h];//插入链表中 head[h] = s;return 1;
}int bfs()  
{init_lookup_table();//初始化查找表 int fron = 1, rear = 2;//fron,当前状态下标,rear,下一步状态下标 while (fron < rear) {State & s = st[fron];   //此时s引用st[fron],s是一维数组,里面有九个元素 if (memcmp(goal, s, sizeof(s)) == 0) return fron;//如果找到目标状态,返回目标状态在st数组下标 int z;for (z = 0; z < 9; z++) if (!s[z]) break;//找0的位置int x = z/3, y = z%3;                    //0的行列编号(0-2)  for (int i = 0; i < 4; i++) {           //上下左右移动零的位置 int newx = x + dx[i];                   int newy = y + dy[i];int newz = newx*3 + newy;       //newz是z移动之后的下标,t[newz]=0.t[z]=s[newz] if (newx >= 0 && newx < 3 && newy >= 0 && newy < 3) {//如果移动合法 State & t = st[rear];   //开一个新的状态 memcpy(&t, &s, sizeof(s));//把之前的状态(那九个元素)先填到新状态里 t[newz] = s[z];         //之前状态中,下标为z的是零,在新状态下,为零的下标变成newz t[z] = s[newz];         dist[rear] = dist[fron] + 1; //更新节点的距离值 (dist【rear】:走到rear状态时的走的步骤个数) if (try_to_insert(rear)) rear++;//如果成功插入查找表,修改队尾指针(也就是从这个支路向外发散) }}fron++;//扩展完毕修改队首指针,也就是从下一个位置开始找 }return 0;//失败 
}int main()
{for (int i = 0; i < 9; i++) scanf("%d", &st[1][i]);//输入初始状态 for (int i = 0; i < 9; i++) scanf("%d", &goal[i]);//输入目标状态 int ans = bfs();// 返回目标状态在st数组下标 if (ans > 0) printf("%d\n", dist[ans]);else printf("-1\n");return 0;
}

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

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

相关文章

变速后没有声音_问答 | 现代朗动at,启动后怠速不稳,热车后正常,是什么问题?...

今日老陈问答Q陈工你好&#xff1a;1.手动家车&#xff0c;停车怠速&#xff0c;有挡或空挡行驶都有异响&#xff0c;踩离合异响消失&#xff0c;抬离合异响恢复&#xff0c;换分离轴承未解决&#xff0c;压板轻磨损没更换&#xff0c;舱室粉末没清理 2.手动挡加自动变速箱油行…

怎么加载文件_Java虚拟机从入门到入土之JVM的类加载机制

作者&#xff1a;六脉神剑转载于&#xff1a;https://juejin.im/post/5e1aaf626fb9a0301d11ac8eJVM总体概述JVM总体上是由类装载子系统(ClassLoader)运行时数据区执行引擎内存回收类文件结构以上5个部分组成&#xff0c;每一个都是非常重要的&#xff0c;如果你要了解JVM&#…

的向上取整函数_计算机二级Excel常用函数解析

决定为大家推点干货让大家学习一下Excel的函数应用ABS绝对值 从最简单的开始第一个是ABS函数简而言之就是取绝对值作用就是MAX&MIN函数 这两个函数是好哥们也比较简单的就是从一堆数字中选出最大值和最小值如图C6格所示ROUND函数 四舍五入函数可不是回合ROUND 1算是比较…

(stl排序+检索)大理石在哪

问题&#xff1a; 现有N个大理石&#xff0c;每个大理石上写了一个非负整数、首先把各数从小到大排序&#xff1b;然后回答Q个问题。每个问题问是否有一个大理石写着某个整数x&#xff0c;如果是&#xff0c;还要回答哪个大理石上写着x。排序后的大理石从左到右编号为1~N。 (…

多个 本地仓库_【运维工具】搭建npm私有镜像仓库,天下苦于npm build久矣

​01 前 言当你的研发团队越来越大&#xff0c;或是你无法忍受node超慢的构建时你可以考虑继续读下去&#xff0c;给大家推荐一个基于Verdaccio相对较完整的解决方案。由于环境的原因&#xff0c;我们直接去 http://npmjs.org 下载就不要考虑了&#xff0c;可以将npm config se…

(STL,vector)木块问题

题目&#xff1a; 输入n&#xff0c;得到编号为0~n-1的木块&#xff0c;分别摆放在顺序排列编号为0~n-1的位置。现对这些木块进行操作&#xff0c;操作分为四种。 1、move a onto b&#xff1a;把木块a、b上方的木块放回各自的原位&#xff0c;再把a放到b上&#xff1b; 2、…

地图自定义图标_如何在H5里添加地图导航?这份教程请收藏!

智能手机的出现为我们的生活带来了翻天覆地的改变&#xff0c;比如说衣食住行都有了显著的变化。外卖让就餐更加方便、手机支付也让生活更加便利&#xff0c;地图导航功能更是让大家从此不再迷路&#xff0c;有了手机以后&#xff0c;大家都开始习惯直接用手机搜索目的地&#…

(STL,set)安迪的第一个字典

问题&#xff1a; 输入一个文本&#xff0c;找出所有不同的单词&#xff08;连续的字母序列&#xff09;&#xff0c;按字典序从小到大输出。单词不区分大小写。 样例输入 Adventures in Disneyland Two blondes were going to Disneyland when they came to a fork in the…

ios 高德获取定位_解决ios11不支持高德地图API定位功能的方法

在 iOS 11 系统上访问JS API定位业务失败怎么解决&#xff1f;苹果新发的 iOS 11 操作系统的一大特性是对 http 形式访问页面的限制变得非常严格(相比iOS 10 和 iOS 9)。高德提供的JS API功能均支持http和https两种协议访问&#xff0c;在iOS 11操作系统上推荐使用https形式访问…

(STL,map)反片语

题目 输入一些单词&#xff0c;找出所有满足如下条件的单词&#xff1a;该单词不能通过字母重排&#xff0c;得到输入文本中的另外一个单词。在判断是否满足条件时&#xff0c;不区分大小写&#xff0c;但输出保留输入中的大小写&#xff0c;按字典序进行排列&#xff08;所有…

源码 状态机_LLVM学习笔记(1)--初探源码

一直耳闻LLVM相比于GCC&#xff1a;well documented架构灵活&#xff0c;前后端解耦符合龙书的讲解昨天读到了一篇虽然概括却很周到的llvm入门导引陈钦霖&#xff1a;LLVM Pass入门导引​zhuanlan.zhihu.com就沿着其中的提示探索了下LLVM源码&#xff0c;倒也没有想要成为专业的…

n个数的最小公倍数

文章目录1.利用公式法求两个数最小公倍数2.最大公约数求法3.求几个数的最小公倍数4.例题1.利用公式法求两个数最小公倍数 假设现在要求最小公倍数的两个数为x,y&#xff0c;他们的最大公约数为p,最小公倍数为q。则xypq 2.最大公约数求法 int gg(int a,int b){int c;while(b)…

cv mat的shape_将ndarray转换为cv::Mat的最简单方法是什么?

正如kyamagu建议的那样&#xff0c;您可以使用OpenCV的官方python包装器代码&#xff0c;尤其是pyopencv_to和{}。在我一直在为所有依赖项和生成的头文件而挣扎。然而&#xff0c;可以通过将^{}作为lightalchemist did here进行“清理”来降低复杂性&#xff0c;以便只保留必要…

c语言年月日问题思路总结 闰年非闰年每个月份的天数 解决今天是妹子出生的第多少天的问题

1.闰年非闰年每个月份的天数&#xff1a; int year[2][13]{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };经观察发现&#xff1a; a。2月闰年有29天&#xff0c;非闰年28天 b。1、3、5、7、8、10、12月份&#xf…

aop判断方法是否执行成功_判断图中是否有环的三种方法

0、什么是环&#xff1f;在图论中&#xff0c;环&#xff08;英语&#xff1a;cycle&#xff09;是一条只有第一个和最后一个顶点重复的非空路径。在有向图中&#xff0c;一个结点经过两种路线到达另一个结点&#xff0c;未必形成环。1、拓扑排序1.1、无向图使用拓扑排序可以判…

reverse()函数反转字符串以及任意类型数组

文章目录reverse用法1.reverse函数反转string2.reverse函数反转字符数组2.自定义reverse函数反转任意类型数组例子&#xff1a;reverse用法 1.reverse函数反转string #include <iostream> #include <algorithm> #include <string> using namespace std;int…

sap运维要做哪些工作_患上腰椎间盘突出,适合做哪些工作?不适合做哪些工作?...

腰椎间盘突出的患者&#xff0c;大多数是年轻人。年轻人生活和工作压力比较大&#xff0c;大多数人都不可能因为腰椎病完全停止工作&#xff0c;事实上也不用完全停止工作&#xff0c;我们更多地应该虑如何平衡养病和工作之间的关系&#xff0c;那我们今天就来和大家讲讲&#…

(STL,map,queue)团体队列

目录 目录题目&#xff1a;分析与解答1.队列先进先出&#xff0c;正好符合排队问题&#xff0c;所以用队列模拟2.每一个团队有一个队列&#xff0c;团队整体又形成一个队列3.每一个团队的成员和团队编号需要对应&#xff0c;因此利用map存编号为x的人所在的团队编号4.插入队&am…

bat执行exe程序_dos命令start教程,并行运行exe程序或者启动bat批处理cmd脚本

大家好&#xff0c;我是老盖&#xff0c;首先感谢观看本文&#xff0c;本篇文章做的有视频&#xff0c;视频讲述的比较详细&#xff0c;也可以看我发布的视频。今天我们学习DOS命令start这个命令&#xff0c;它可以启动一个EXE程序&#xff0c;也可以启动一个BAT批处理脚本&…

(STL,set,priority_queue)丑数

题目&#xff1a; 丑数是指不能被2,3,5以外的其他素数整除的数。把丑数从小到大排列起来&#xff0c;结果如下&#xff1a;1,2,3,4,5,6,8,9,10,12,…求第1500个丑数 分析与解答&#xff1a; 0.对于任意丑数x&#xff1a;2x&#xff0c;3x&#xff0c;5x也是丑数 1.用优先队…