转自洛谷 作者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. Jquery 获取控件的值

    1:通过控件的ID 获取值 $("input[name='weiKuanDate']").val(); 2:通过控件的name 获取值 $("input[name='we ...

  2. Centos7 mariadb (mysql)主从复制实现

    一.mysql基本命令 .启动mysql systemctl start mariadb .linux客户端连接自己 mysql -uroot -p -h 127.0.0.1 .远程链接mysql服务 ...

  3. 119、Java中String类之通过isEmpty判断是否为空字符串

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  4. 按钮UIButton的使用

    一.使用概要 当添加一个按钮到你的界面,执行以下步骤: 1.在创建时设置按钮的类型. 2.提供一个标题字符串或图像,为您的内容适当调整按钮的大小. 3.连接一个或多个操作按钮的方法. 4.设置自动布局 ...

  5. JavaScript 的数据类型

    一.分类 根据 JavaScript 中的变量类型传递方式,分为基本数据类型和引用数据类型.其中基本数据类型包括Undefined.Null.Boolean.Number.String.Symbol ...

  6. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 辅助类:"text-danger" 类的文本样式

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

  7. 【转】iPhone/IOS使用Fiddler抓包配置

    原文链接:https://blog.csdn.net/weixin_39198406/article/details/81123716 1. 安装 安装Fiddler软件2. 配置2.1 端口 点击 ...

  8. python设置编码

    import sys sys.getdefaultencoding() #看到默认编码是'ascii' #通常需要的是使用utf8编码,需要这样做: reload(sys) sys.setdefaul ...

  9. 在Gridview控件中根据Field Name来取得对应列索引

    下面方法,只能在Gridview的BoundField进行操作,而在TemplateField模版中去找的话,就无能为力了,因TemplateField模版没有DataField属性.  public ...

  10. JavaWeb--概述

    1.Java Web应用由一组Servlet.HTML页.类以及其他可以被绑定的资源构成.它可以在何种供应商提供的实现Servlet规范的Servlet容器中运行: 2.Java Web应用中包含如下 ...