题目地址:

https://www.luogu.com.cn/problem/P1379

题目描述:
在3×33×33×3的棋盘上,摆有八个棋子,每个棋子上标有111至888的某一数字。棋盘中留有一个空格,空格用000来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。

输入格式:
输入初始状态,一行九个数字,空格用000表示

输出格式:
只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊无法到达目标状态数据)

一个很优的做法是用A*算法来做。启发函数可以参考https://blog.csdn.net/qq_46105170/article/details/122184375。那里用的是IDA*算法来做的,这里用A*来做。代码如下:

#include <iostream>
#include <queue>
#include <unordered_map>
using namespace std;
using PIS = pair<int, string>;string s, ed = "123804765";
int d[] = {-1, 0, 1, 0, -1};
int pos[9];
unordered_map<string, int> dist;
priority_queue<PIS, vector<PIS>, greater<>> heap;// 求s和ed的各个数字的曼哈顿距离之和
int h(string &s) {int dis = 0;for (int i = 0; i < 9; i++) {if (s[i] == '0') continue;int x = i / 3, y = i % 3;int xx = pos[s[i] - '0'] / 3, yy = pos[s[i] - '0'] % 3;dis += abs(x - xx) + abs(y - yy);}return dis;
}int Astar() {dist[s] = 0;heap.push({h(s), s});while (heap.size()) {auto t = heap.top(); heap.pop();s = t.second;if (s == ed) return dist[s];int idx = 0;while (s[idx] != '0') idx++;int x = idx / 3, y = idx % 3;for (int i = 0; i < 4; i++) {string ss = s;int xx = x + d[i], yy = y + d[i + 1];if (0 <= xx && xx < 3 && 0 <= yy && yy < 3) {swap(ss[idx], ss[xx * 3 + yy]);if (!dist.count(ss) || dist[ss] > dist[s] + 1) {dist[ss] = dist[s] + 1;heap.push({dist[ss] + h(ss), ss});}}}}return -1;
}int main() {cin >> s;for (int i = 0; i < 9; i++) pos[ed[i] - '0'] = i;printf("%d\n", Astar());return 0;
}

时空复杂度取决于具体数据。

【洛谷】P1379 八数码难题相关推荐

  1. 洛谷—P1379 八数码难题

    题目链接:P1379 八数码难题 题目大意: 要求最少步骤的移动方法,实现从初始布局到目标布局的转变. 解题思路: 这道题目要用到搜索中比较难的搜索方法-迭代加深的A*算法.所谓迭代加深就是每次限制搜 ...

  2. 洛谷P1379八数码难题

    题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中. 要求解的问题是:给出一种初始布局(初始状态)和目标布局(为 ...

  3. [洛谷] P1379 八数码难题( 提高+/省选- )

    八数码 1.题目 2.分析 3.代码 1. bfs (+queue) + unordered_map 重点分析 2.双向bfs (适用于知道起始状态的情况) 思路分析 3.双向bfs优化 思路 4.总 ...

  4. IDA*-洛谷P1379 八数码难题

    https://daniu.luogu.org/problem/show?pid=1379 省选的收获 暗金 学会了A*啦啦啦: 我在第一天学了A*; 然后回家颓废之余思考思考: 又问了van爷一些小 ...

  5. 洛谷 1379 八数码难题

    题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了 ...

  6. P1379 八数码难题 题解(双向宽搜)

    博客园同步 原题链接 简要题意: 给定一个 3 × 3 3 \times 3 3×3 的矩阵,每次可以把空格旁边(四方向)的一个位置移到空格上.求到目标状态的最小步数. 前置知识: 单向宽搜的写法 O ...

  7. 洛谷OJ:P1379 八数码难题(双向搜索)

    思路:相信不少小伙伴上来就是暴力DFS,但是拿到题之后我们不妨想一想如果纯DFS爆搜下来会产生多少种状态,这样的方法是否是最优的? 这里选择使用一种称之为双向搜索的方法(通过知乎学到的,放出来shar ...

  8. 习题:八数码难题(双向BFS)

    八数码难题(wikioi1225) [题目描述] 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出 ...

  9. 【codevs1225】八数码难题,如何精确地搜索

    1225 八数码难题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description Yours和zero在研究A*启发式算法.拿到一道 ...

最新文章

  1. Blender三维插图设计视频教程 3D Characters and Illustrations in Blender 2.9
  2. matplotlib绘制3维图
  3. NB-IOT来了,物联网时代才真正来临
  4. spring访问oracle函数,spring调用带参数的oracle函数应注意的问题
  5. Database之SQLSever:SQLSever基础知识进阶、软件安装注意事项、软件使用经验总结之详细攻略
  6. 加mp4文件后js失效_Jquery方法load之后导致js失效解决方法
  7. 报告!钉钉宜搭的8月总结,请查收~
  8. 关于 Orbeon form PE 版本使用 JavaScript Embedding API 的一个例子
  9. 机器学习笔记(五):逻辑回归
  10. [Lab 2] OSPF专题
  11. amap vueamap 与_vue中使用vue-amap(高德地图)
  12. 爱可生 mysql监控_MySQL 数据传输DTLE 最新版来啦-爱可生
  13. yum提示Another app is currently holding the yum lock; waiting for it to exit...处理办法
  14. /proc/meminfo之谜
  15. 原来excel也能做职业数据分析(步骤完整且过程详细)
  16. 二叉平衡树的基本操作(完整代码)
  17. 矩阵的转置与矩阵的逆
  18. 算法介绍 | 泛洪算法(Flood fill Algorithm)
  19. [论文阅读] (26) 基于Excel可视化分析的论文实验图表绘制总结——以电影市场为例
  20. java《面向对象综合题》

热门文章

  1. 没学c语言可以学python_没学过c语言 可以直接学Python吗
  2. Java程序:开发一个应用,模拟计算机对移动存储设备的读写,即移动存储设备有U盘、手机卡、移动硬盘、闪卡等设备
  3. click事件和onclick事件的区别
  4. 三言两语搞懂c语言之struct与typedef(小白必看)
  5. Java手机号码校验工具类
  6. 魂斗罗归来大觉机器人_魂斗罗归来Boss模式详解 Boss血量分析
  7. C语言中的time函数
  8. php平均成绩,并划分等级
  9. 基于云边协同架构的五大应用场景革新
  10. 前端使用js-audio-recorder组件实现录音、语音下载、播放等【含blob对象转换为file对象】