这个看起来是童年回忆:)

大体思路是,将每个排列状态看成图中的一个点,状态之间转换说明有边。然后用bfs,如果遍历完之后还是没有找到目标状态,

则说明是无解的,否则输出步数。具体想法写在代码里吧,多多理解。

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string.h>
#include <cmath>
#include <vector>
#include <algorithm> using namespace std;
const int N = 1000000, HN = 1000003;
// linked list for hash table.
int head[HN], next[N];
int state[N][9], goal[9];
// # steps
int dist[N];
const int dx[4] = {-1, 1, 0, 0};
const int dy[4] = {0, 0, -1, 1}; // map into a number of 9 digits
int hash(int *arr) {
int v = 0;
for (int i = 0; i < 9; i++) {
v = v * 10 + arr[i];
}
// make sure not overflow
return v % HN;
}
// insert a state
bool tryInsert(int rear) {
int h = hash(state[rear]);
int u = head[h];
while (u) {
// if repeated
if (!memcmp(state[u], state[rear], sizeof(state[0])))
return false;
u = next[u];
}
// insert rear to the front
next[rear] = head[h];
head[h] = rear;
return true;
}
int bfs() {
// initiate head
memset(head, 0, sizeof(head));
//memset(dist, 0, sizeof(dist));
int front = 1;
int rear = 2;
while (front < rear) {
// same, memcmp return 0
// means find goal
if (!memcmp(goal, state[front], sizeof(state[0])))
return front;
int z;
// find 0
for (z = 0 ; z < 9; z++)
if (!state[front][z])
break;
int x = z / 3;
int y = z % 3;
for (int d = 0; d < 4; d++) {
int nx = x + dx[d];
int ny = y + dy[d];
int nz = 3 * nx + ny;
// judge if still in
if (nx >= 0 && nx < 3 && ny >= 0 && ny < 3) {
memcpy(&state[rear], &state[front], sizeof(state[0]));
// move
state[rear][nz] = state[front][z];
state[rear][z] = state[front][nz];
dist[rear] = dist[front] + 1;
if (tryInsert(rear))
rear ++;
}
}
// front pop
front ++;
}
return 0;
}
int main() {
//freopen("hhInput.in", "r", stdin);
for (int i = 0; i < 9; i++)
// 1 3 0 8 2 4 7 6 5
cin >> state[1][i];
for (int i = 0; i < 9; i++)
// 1 2 3 8 0 4 7 6 5
cin >> goal[i];
int ans = bfs();
if (ans > 0)
cout << dist[ans] << endl;
else
cout << "-1" << endl;
return 0;
}

  

graph-bfs-八数码问题的更多相关文章

  1. BFS(八数码) POJ 1077 || HDOJ 1043 Eight

    题目传送门1 2 题意:从无序到有序移动的方案,即最后成1 2 3 4 5 6 7 8 0 分析:八数码经典问题.POJ是一次,HDOJ是多次.因为康托展开还不会,也写不了什么,HDOJ需要从最后的状 ...

  2. UVALive 6665 Dragon’s Cruller --BFS,类八数码问题

    题意大概就是八数码问题,只不过把空格的移动方式改变了:空格能够向前或向后移动一格或三格(循环的). 分析:其实跟八数码问题差不多,用康托展开记录状态,bfs即可. 代码: #include <i ...

  3. [cdoj1380] Xiper的奇妙历险(3) (八数码问题 bfs + 预处理)

    快要NOIP 2016 了,现在已经停课集训了.计划用10天来复习以前学习过的所有内容.首先就是搜索. 八数码是一道很经典的搜索题,普通的bfs就可求出.为了优化效率,我曾经用过康托展开来优化空间,甚 ...

  4. 八数码问题+路径寻找问题+bfs(隐式图的判重操作)

    Δ路径寻找问题可以归结为隐式图的遍历,它的任务是找到一条凑够初始状态到终止问题的最优路径, 而不是像回溯法那样找到一个符合某些要求的解. 八数码问题就是路径查找问题背景下的经典训练题目. 程序框架 p ...

  5. HDU 1043 Eight (BFS&#183;八数码&#183;康托展开)

    题意  输出八数码问题从给定状态到12345678x的路径 用康托展开将排列相应为整数  即这个排列在全部排列中的字典序  然后就是基础的BFS了 #include <bits/stdc++.h ...

  6. 【算法】BFS+哈希解决八数码问题

    15拼图已经有超过100年; 即使你不叫这个名字知道的话,你已经看到了.它被构造成具有15滑动砖,每一个从1到15上,并且所有包装成4乘4帧与一个瓦块丢失.让我们把丢失的瓷砖“X”; 拼图的目的是安排 ...

  7. hdu-1043(八数码+bfs打表+康托展开)

    参考文章:https://www.cnblogs.com/Inkblots/p/4846948.html 康托展开:https://blog.csdn.net/wbin233/article/deta ...

  8. Poj 1077 eight(BFS+全序列Hash解八数码问题)

    一.题意 经典的八数码问题,有人说不做此题人生不完整,哈哈.给出一个含数字1~8和字母x的3 * 3矩阵,如: 1  2  X            3 4  6            7  5  8 ...

  9. HDU1043 八数码(BFS + 打表)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 , 康托展开 + BFS + 打表. 经典八数码问题,传说此题不做人生不完整,关于八数码的八境界 ...

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

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

随机推荐

  1. hibernate Restrictions用法 HibernateTemplate Hibernate结合spring

    常用方法 http://www.jb51.net/article/41541.htm ........................................... 博客分类: Hiberna ...

  2. Testlink设置

    1. Testlink配置修改 1.1. config.inc.php 1.1.1. 日志路径配置 /** * @var string Path to store logs - *for securi ...

  3. opencv 形态学膨胀和腐蚀以及开运算和闭运算

  4. fleet-运行一个全局的单元

    运行一个全局的单元 正如前面所提到的,全局单元是有用的,用于在您的集群中的所有机器上运行一个单元.它不会比一个普通的单元差太多,而是一个新的x-fleet参数称为Global=true.这是一个示例单 ...

  5. IDEA对比文件

    和另一个文件对比:右击文件,选择另一个文件 和剪切板的内容对比:右击代码区域

  6. SpringMVC注解方式与文件上传

    目录: springmvc的注解方式 文件上传(上传图片,并显示) 一.注解 在类前面加上@Controller 表示该类是一个控制器在方法handleRequest 前面加上 @RequestMap ...

  7. springBoot jpa 表单关联查询

    1.创建两个实体类 import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.per ...

  8. JFinal教程:JFinal极速开发企业实战百集JFinal视频教程发布

    课程名称:JFinal极速开发企业实战 课程长度:100课时 课程作者:小木(909854136) 课程地址:http://edu.csdn.net/course/detail/1968 官网网址:h ...

  9. Python之邮件发送

    Python的smtplib提供了一种很方便的途径用来发送电子邮件,它有SMTP协议进行简单的封装,可以使用SMTP对象的sendmail方法发送邮件,通过help()查看SMTP所提供的方法如下: ...

  10. 事务回滚 DEMO

    因为有些事物回滚  查询的时候 可能查出来空值 我们肯定不愿意把空值添加数据库里面 一般基本的是这么写 if (object_id('add_T_Disclose_DiscloseList', 'P' ...