转自洛谷 作者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. 第二天python

    1.pycharm的安装: 1.先去官网下载软件:https://www.jetbrains.com/pycharm/download/#section=windows然后进行下一步,下一步操作既可以 ...

  2. 监听EditView中的文本改变事件详解--转

    转自: http://blog.csdn.net/zoeice/article/details/7700529 android中的编辑框EditText也比较常用,那比如在搜索框中,没输入一个字,下面 ...

  3. Controller 层类

    package com.thinkgem.jeesite.modules.yudengji.web; import java.util.Date; import javax.servlet.http. ...

  4. 线程安全Collections.synchronizedList

    ollections.synchronizedList引发的线程安全问题 有些容器是线程安全的(Vector,ConcurrentLinkedQueue等),有些则不是(list等),利用类 似 pr ...

  5. 洛谷 P6046 [CTSC2000]快乐的蜜月

    先讲解一下如何处理这道题的毒瘤输入.\(m\) 和 \(d\) 之间的"/"和" TO "都可以用 getchar() 强行吃掉,日期的转换可以用公式 \(s_ ...

  6. python表白代码1.0桃心输出

    python爱心表达函数初级版本:def my_heart(a,b=2): print("\n".join(["".join([(a[(x-y) % len(a ...

  7. alerm和pause

    pause函数,会让进程进入阻塞状态,收到信号时,会中断这个阻塞的系统调用 alerm(s),会设置进程闹钟,在指定的时间后,进程会收到SIG_ALERM信号,收到这个信号时,可以中断pause阻塞调 ...

  8. Oracle笔记--Sql语句

    1.SQL的三种类型语句: --1)DML(Data Manipulation Language)数据操纵语言 --2)DDL(Data Definition Language):数据定义语言 --3 ...

  9. Day9 - C - Bookshelf 2 POJ - 3628

    Farmer John recently bought another bookshelf for the cow library, but the shelf is getting filled u ...

  10. Day3-H-Alice and Bob HDU4268

    Alice and Bob's game never ends. Today, they introduce a new game. In this game, both of them have N ...