graph-bfs-八数码问题

这个看起来是童年回忆:)
大体思路是,将每个排列状态看成图中的一个点,状态之间转换说明有边。然后用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-八数码问题的更多相关文章
- BFS(八数码) POJ 1077 || HDOJ 1043 Eight
题目传送门1 2 题意:从无序到有序移动的方案,即最后成1 2 3 4 5 6 7 8 0 分析:八数码经典问题.POJ是一次,HDOJ是多次.因为康托展开还不会,也写不了什么,HDOJ需要从最后的状 ...
- UVALive 6665 Dragonâs Cruller --BFS,类八数码问题
题意大概就是八数码问题,只不过把空格的移动方式改变了:空格能够向前或向后移动一格或三格(循环的). 分析:其实跟八数码问题差不多,用康托展开记录状态,bfs即可. 代码: #include <i ...
- [cdoj1380] Xiper的奇妙历险(3) (八数码问题 bfs + 预处理)
快要NOIP 2016 了,现在已经停课集训了.计划用10天来复习以前学习过的所有内容.首先就是搜索. 八数码是一道很经典的搜索题,普通的bfs就可求出.为了优化效率,我曾经用过康托展开来优化空间,甚 ...
- 八数码问题+路径寻找问题+bfs(隐式图的判重操作)
Δ路径寻找问题可以归结为隐式图的遍历,它的任务是找到一条凑够初始状态到终止问题的最优路径, 而不是像回溯法那样找到一个符合某些要求的解. 八数码问题就是路径查找问题背景下的经典训练题目. 程序框架 p ...
- HDU 1043 Eight (BFS·八数码·康托展开)
题意 输出八数码问题从给定状态到12345678x的路径 用康托展开将排列相应为整数 即这个排列在全部排列中的字典序 然后就是基础的BFS了 #include <bits/stdc++.h ...
- 【算法】BFS+哈希解决八数码问题
15拼图已经有超过100年; 即使你不叫这个名字知道的话,你已经看到了.它被构造成具有15滑动砖,每一个从1到15上,并且所有包装成4乘4帧与一个瓦块丢失.让我们把丢失的瓷砖“X”; 拼图的目的是安排 ...
- hdu-1043(八数码+bfs打表+康托展开)
参考文章:https://www.cnblogs.com/Inkblots/p/4846948.html 康托展开:https://blog.csdn.net/wbin233/article/deta ...
- Poj 1077 eight(BFS+全序列Hash解八数码问题)
一.题意 经典的八数码问题,有人说不做此题人生不完整,哈哈.给出一个含数字1~8和字母x的3 * 3矩阵,如: 1 2 X 3 4 6 7 5 8 ...
- HDU1043 八数码(BFS + 打表)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 , 康托展开 + BFS + 打表. 经典八数码问题,传说此题不做人生不完整,关于八数码的八境界 ...
- 习题:八数码难题(双向BFS)
八数码难题(wikioi1225) [题目描述] 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出 ...
随机推荐
- php时间戳存在8小时误差
当将PHP时间戳转化为正常的时间格式一般的操作方法如下: $mytime=time(); echo $mytime.'<br />'; echo date('Y-m-d H:i:s',$m ...
- QrenCode : linux命令行下生成二维码图片
原文链接:http://wowubuntu.com/qrencode.html # 作者:riku/ / 本文采用CC BY-NC-SA 2.5协议授权,转载请注明本文链接. 对于二维码大家应该并不陌 ...
- mysql 中unsigned
整型的每一种都分有无符号(unsigned)和有符号(signed)两种类型(float和double总是带符号的),在默认情况下声明的整型变量都是有符号的类型(char有点特别),如果需声明无符号类 ...
- 编写Servlet,验证用户登录,如果用户名与密码都为“admin”则验证通过,跳转欢迎页面,否则弹出提示信息“用户名或密码错误,请重新输入!”,点击“确定”后跳转至登录页面
java代码:(Test1) package com.test; import java.io.IOException; import java.io.PrintWriter; import java ...
- CSS布局技巧之——各种居中
居中是我们使用css来布局时常遇到的情况.使用css来进行居中时,有时一个属性就能搞定,有时则需要一定的技巧才能兼容到所有浏览器,本文就居中的一些常用方法做个简单的介绍. 注:本文所讲方法除了特别说明 ...
- js动态生成canvas
最近看代码发现一个小现象,就是用js动态生成的canvas在浏览器审查元素的时候,发现它没有结束标签,但是不会影响canvas上图形的绘制,同时还有一点就是在动态设置canvas宽度和高度的时候,不要 ...
- Eclipse IDE配置PHP开发、调试环境
前言 使用java语言开发的朋友想必对Eclipse开发工具已经不陌生了,那么Eclipse作为java主流的开发工具,是否能够开发PHP项目呢?答案如你所想,肯定是可以的!以下就是该IDE下如何配置 ...
- ADO.Net——增、删、改、查
数据访问 对应命名空间:System.Data.SqlClient; SqlConnection:连接对象 SqlCommand:命令对象 SqlDataReader:读取器对象 CommandTex ...
- 解决Layui的switch样式显示问题
Layui官方文档是这么说的: <input type="checkbox" name="xxx" lay-skin="switch" ...
- jsp另外五大内置对象之config
//配置web.xml <?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi=&q ...