转自洛谷 作者EndSaH

#include<iostream>
#include<string>
#include<cmath>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#include<queue>
#include<stack>
#include<sstream>
#include<cstdio>
#define INF 0x3f3f3f3f
//const int maxn = 1e6 + 5;
const double PI = acos(-1.0);
typedef long long ll;
using namespace std; const int mod1 = 1e5 + , mod2 = 1e6 + ;
const int dx[] = { ,,,- }, dy[] = { ,-,, }; bool flag;
int ans; struct Node {
int key, step;
bool head;
Node* next;
Node() { key = step = head = ; next = NULL; }
}Hash[mod1+]; struct CB {
int value[][];
int spx, spy, step;
void init() {
value[][] = ;
value[][] = ;
value[][] = ;
value[][] = ;
value[][] = ;
value[][] = ;
value[][] = ;
value[][] = ;
value[][] = ;
spx = ;
spy = ;
}
bool operator ==(const CB& x)const {
for (int i = ; i < ; i++) {
for (int j = ; j < ; j++) {
if (value[i][j] != x.value[i][j]) return false;
}
}
return true;
}
}start,goal; bool Querry(const CB& x, bool head) {
int num = ;
int sum1, sum2;
for (int i = ; i < ; i++) {
for (int j = ; j < ; j++) num = num * + x.value[i][j];
}
sum1 = num % mod1, sum2 = num % mod2;
if (!Hash[sum1].key) {
Hash[sum1].key = sum2;
Hash[sum1].head = head;
Hash[sum1].step = x.step;
return true;
}
if (Hash[sum1].key == sum2) {
if (head != Hash[sum1].head) {
flag = true;
ans = x.step + Hash[sum1].step;
}
return false;
}
else {
Node* now = &Hash[sum1];
while (now->next) {
now = now->next;
if (now->key == sum2) {
if (head != now->head) {
flag = true;
ans = now->step + x.step;
}
return false;
}
}
Node* newnode = new Node;
newnode->key = sum2;
newnode->head = head;
now->next = newnode;
return true;
}
} void bfs() {
queue<CB> q1;
queue<CB> q2;
start.step = goal.step = ;
q1.push(start);
q2.push(start);
while () {
if (q1.size() > q2.size()) {
CB now = q2.front();
q2.pop();
for (int i = ; i < ; i++) {
int xx = now.spx + dx[i], yy = now.spy + dy[i];
if (xx < || xx >> || yy < || yy>) continue;
CB wib = now;
wib.step = now.step + ;
wib.spx = xx, wib.spy = yy;
swap(wib.value[xx][yy], wib.value[now.spx][now.spy]);
if (Querry(wib, )) q2.push(wib);
if (flag) return;
}
}
else {
CB now = q1.front();
q1.pop();
for (int i = ; i < ; i++) {
int xx = now.spx + dx[i], yy = now.spy + dy[i];
if (xx < || xx> || yy < || yy>) continue;
CB wib = now;
swap(wib.value[xx][yy], wib.value[now.spx][now.spy]);
wib.spx = xx, wib.spy = yy;
wib.step = now.step + ;
if (Querry(wib, )) q1.push(wib);
if (flag) return;
}
}
if (flag) return;
}
} int main() {
char ch;
for (int i = ; i < ; i++) {
for (int j = ; j > ; j++) {
scanf("%c", &ch);
if (ch == '') start.spx = i, start.spy = j;
start.value[i][j] = ch - '';
}
}
goal.init();
if (goal == start) {
printf("");
}
else {
bfs();
printf("%d", ans);
}
return ;
}

八数码问题 双向BFS/Hsh链表存储的更多相关文章

  1. HDOJ-1043 Eight(八数码问题+双向bfs+高效记录路径+康拓展开)

    bfs搜索加记录路径 HDOJ-1043 主要思路就是使用双向广度优先搜索,找最短路径.然后记录路径,找到结果是打印出来. 使用康拓序列来来实现状态的映射. 打印路径推荐使用vector最后需要使用a ...

  2. cdoj 414 八数码 (双向bfs+康拓展开,A*)

    一道关乎人生完整的问题. DBFS的优越:避免了结点膨胀太多. 假设一个状态结点可以扩展m个子结点,为了简单起见,假设每个结点的扩展都是相互独立的. 分析:起始状态结点数为1,每加深一层,结点数An ...

  3. hdu1043 经典的八数码问题 逆向bfs打表 + 逆序数

    题意: 题意就是八数码,给了一个3 * 3 的矩阵,上面有八个数字,有一个位置是空的,每次空的位置可以和他相邻的数字换位置,给你一些起始状态 ,给了一个最终状态,让你输出怎么变换才能达到目的. 思路: ...

  4. 【洛谷】P1379 八数码难题(bfs)

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

  5. HDU 1043 Eight 【经典八数码输出路径/BFS/A*/康托展开】

    本题有写法好几个写法,但主要思路是BFS: No.1 采用双向宽搜,分别从起始态和结束态进行宽搜,暴力判重.如果只进行单向会超时. No.2 采用hash进行判重,宽搜采用单向就可以AC. No.3 ...

  6. hdu 1043 Eight (八数码问题)【BFS】+【康拓展开】

    <题目链接> 题目大意:给出一个3×3的矩阵(包含1-8数字和一个字母x),经过一些移动格子上的数后得到连续的1-8,最后一格是x,要求最小移动步数. 解题分析:本题用BFS来寻找路径,为 ...

  7. HDU1043 Eight(八数码:逆向BFS打表+康托展开)题解

    Eight Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  8. 洛谷——P1379 八数码难题

    P1379 八数码难题 双向BFS 原来双向BFS是这样的:终止状态与起始状态同时入队,进行搜索,只不过状态标记不一样而已,本题状态使用map来存储 #include<iostream> ...

  9. 双向BFS和启发式搜索的应用

    题目链接 P5507 机关 题意简述   有12个旋钮,每个旋钮开始时处于状态 \(1\) ~ \(4\) ,每次操作可以往规定方向转动一个旋钮 (\(1\Rightarrow2\Rightarrow ...

随机推荐

  1. A*算法和K短路(A*)

    堪称最好的A算法 https://blog.csdn.net/b2b160/article/details/4057781 K短路(A) https://www.jianshu.com/p/27019 ...

  2. 第4节 Scala中的actor介绍:1、actor概念介绍;2、actor执行顺序和发送消息的方式

    10.    Scala Actor并发编程 10.1.   课程目标 10.1.1.    目标一:熟悉Scala Actor并发编程 10.1.2.    目标二:为学习Akka做准备 注:Sca ...

  3. 使用 TestFight 构建 Beta 测试版本

    ---恢复内容开始--- Beta测试属于软件开发周期中的一环,测试的重点就是让一些活生生的人去使用你的App,不断测试然后反馈.你需要让你的测试成员发现尽可能多的bug,以便你在公开发布之前将其修复 ...

  4. Nodejs回调加超时限制两种实现方法

    odejs回调加超时限制两种实现方法 Nodejs下的IO操作都是异步的,有时候异步请求返回太慢,不想无限等待回调怎么办呢?我们可以给回调函数加一个超时限制,到一定时间还没有回调就表示失败,继续后面的 ...

  5. Python 全国考级二级

    第1章  Python概述 [Python语言简介] Python是一种跨平台.开源.免费的解释型高级动态编程语言,是一种通用编程语言. Python支持命令式编程和函数式编程两种方式,并且完全支持面 ...

  6. 百度云bae安装discuz论坛教程

    作者:孤风一剑   发布:2013-05-11 13:37   栏目:站长在线   点击:6,846次   41条评论 各位草根们有福啦,弄了几天,终于可以在bae上搭建discuz论坛了,下面我就简 ...

  7. 用Total Commander替换windos默认资源管理器的方法

    Total Commander(简称TC)是一个功能强大的资源管理器. TC本身没有自带的替换windows资源管理器的功能,就必须自己动手解决了. 第一步先Google一下看有没有答案.当时搜出了不 ...

  8. redis之五大数据类型介绍

    目录 redis五大数据类型 1. string(字符串) 特点: 格式: 基本操作: 2. hash(哈希) 特点: 格式: 基本操作 3. list(列表) 特点 格式 基本操作 4. set(集 ...

  9. http-equiv属性的属性值X-UA-Compatible

    参考:https://blog.csdn.net/changjiangbuxi/article/details/26054755

  10. activity添加切换动画之后出现的黑色背景问题

    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">     & ...