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

大体思路是,将每个排列状态看成图中的一个点,状态之间转换说明有边。然后用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. Linux (Windows Linux子系统)

    Linux (Windows Linux子系统) 如果想体验Linux环境下开发和运行.NET Core应用,我们有多种选择.一种就是在一台物理机上安装原生的Linux,我们可以根据自身的喜好选择某种 ...

  2. HDU 1029 一道微软面试题

    http://acm.hdu.edu.cn/showproblem.php?pid=1029 给定一个数组,其中有一个相同的数字是出现了大于等于(n + 1) / 2次的.要求找出来. 1.明显排序后 ...

  3. (转)Nginx的https配置记录以及http强制跳转到https的方法梳理

    Nginx的https配置记录以及http强制跳转到https的方法梳理 原文:http://www.cnblogs.com/kevingrace/p/6187072.html 一.Nginx安装(略 ...

  4. Redis key 键

    1.set key value    //设置.修改值 2.get key  //如果key不存在,返回nil,表示空. 3.type key   //返回key对应的value的数据类型 4.ren ...

  5. linux 环境下备份oracle 数据库

    登陆linux后,进入oracle的安装目录下,找到bin那个目录,进入bin目录ls -l 看这些命令的所有者: su - oracle这时会进入这个用户的主目录/home/oracle,此时,可以 ...

  6. DHTMLX 使用汇总

    1.dhtmlxGrid  底部总出现滚动条 ------------------------------------------ 发现使用DHTMLXGRID时 GRID 底边总有   滚动条 测试 ...

  7. 零基础逆向工程17_PE结构01_PE头解析_手动

    PE文件的两种状态 1.在硬盘中 节省硬盘空间 硬盘对齐 内存对齐 2.在内存中 3.PE磁盘文件与内存映像结构图 PE文件为什么要分节 -- 手动解析:PE文件 分析软件:飞鸽传书http://ww ...

  8. <转>Java 高并发综合

    并发模型 悲观锁和乐观锁的理解及如何实现,有哪些实现方式? 悲观锁 悲观锁假设最坏的情况(如果你不锁门,那么捣蛋鬼就会闯入并搞得一团糟),并且只有在确保其他线程不会干扰(通过获取正确的锁)的情况下才能 ...

  9. 2012-2013 ACM-ICPC, NEERC, Central Subregional Contest H Milestones1 (暴力)

    预处理+暴力,每个颜色都是独立的,求个前缀和,减一减判断一个在区间内颜色是否存在. 算了算复杂度好像有点勉强,但是还是过了,学了主席树以后用主席树在做一下 #include<bits/stdc+ ...

  10. Distinct Values(贪心)

    问题 D: Distinct Values 时间限制: 1 Sec  内存限制: 128 MB提交: 13  解决: 5[提交] [状态] [讨论版] [命题人:admin] 题目描述 Chiaki ...