转自洛谷 作者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. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 显示代码:同一行代码片段: span, div

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  2. JS原型与原型链继承的理解

    一.原型 先从构造函数开始吧! 构造函数是什么?构造函数与其他函数唯一的区别在于调用方式不同.任何函数只要通过new来调用就可以作为构造函数,它是用来创建特定类型的对象. 下面定义一个构造函数 Fem ...

  3. Eth合约攻击续

    合同代表一个非常简单的游戏:谁给它发送了比当前奖金还大的数量的以太,就成为新的国王.在这样的事件中,被推翻的国王获得了新的奖金,但是如果你提交的话那么合约就会回退,让level重新成为国王,而我们的目 ...

  4. 浏览器控制台报Cannot read property 'conf' of undefined

    原因:JS中有个变量没有类型导致 解决:加上类型即可(我是少写了var)

  5. redhat 7.6 配置repo源

    vi /etc/yum.repos.d/base.repo          #编辑配置repo配置文件,如果没有则自动创建,没有影响 name=base     //源名字,起什么名都没影响 bas ...

  6. 解决 U2000 R017 安装报错: 检查SQL server数据库环境变量信息 ( 异常 ) [ 详细信息 ] PATH环境变量中缺少数据库路径的信息

    U2000 R017 安装报错: 检查SQL server数据库环境变量信息 ( 异常 ) [ 详细信息 ] PATH环境变量中缺少数据库路径的信息 管理员模式打开注册表位置: HKEY_LOCAL_ ...

  7. 查漏补缺之Go的Strings, bytes, runes和字符

    字节遍历,字符遍历 https://play.golang.org/p/DeZcCN9aHXo package main import ( "fmt" "unicode/ ...

  8. NetCore Web项目目录结构说明

    目录结构说明 目录/文件 说明 依赖项 ASP.NET Core 开发.构建和运行过程中的依赖想,一般都是 NuGet 包和一些 SDK Properties 配置,存放了一些 .json 文件用于配 ...

  9. request-html

    目录 基本使用 获取链接( links 与 absolute_links ) CSS 选择器与 XPATH 支持 JavaScript 自定义 User-Agent 模拟表单提交(POST) asyn ...

  10. layer弹出框包含页面

    参考:http://www.cnblogs.com/zhengchenhui/p/6038865.html