思路:相信不少小伙伴上来就是暴力DFS,但是拿到题之后我们不妨想一想如果纯DFS爆搜下来会产生多少种状态,这样的方法是否是最优的?

这里选择使用一种称之为双向搜索的方法(通过知乎学到的,放出来share一下),具体来说就是若已知初始状态和终止状态下我们同时从起点和终点开始DFS【当然也有BFS写法,这里先用DFS】,和普通DFS不同的是,我们每次DFS的时候都会规定一个最大深度,而这个最大深度是递增的,例如第一次DFS的时候最大深度D=0,第二次为1,...,以此类推,而每次更新完D后需要从起点和终点重新出发DFS。

但是可能很多人会有疑问,每次这样重复的从头开始搜,岂不是比爆搜还慢???我们看一张图先【图片出处:https://zhuanlan.zhihu.com/p/119349440】:

我们发现这个通过爆搜得到的解答树其复杂度往往是由树的最后一层叶子节点的数量决定的!因此我们的双向搜索算法能达到和广搜相近的时间复杂度,并且能够换来比BFS更低的空间复杂度!

#include<set>
#include<map>
#include<queue>
#include<vector>
#include<string>
#include<math.h>
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<functional>
#include<unordered_map>
using namespace std;
#define inf 1e18
#define maxn 2005
#define ll long long
int D;
int e[]={1,10,100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000};
bool found;
unordered_map<int,int> H;
int findZero(int x,int i){return x%e[i+1]/e[i];
}
int swapPos(int x,int p,int i){return x-findZero(x,i)*e[i]+findZero(x,i)*e[p];
}
void dfs(int x,int p,int d,int dir){if(H[x]+dir==3)found=true;H[x]=dir;if(d==D) return;if(p/3) dfs(swapPos(x,p,p-3),p-3,d+1,dir);if(p/3!=2) dfs(swapPos(x,p,p+3),p+3,d+1,dir);if(p%3) dfs(swapPos(x,p,p-1),p-1,d+1,dir);if(p%3!=2) dfs(swapPos(x,p,p+1),p+1,d+1,dir);
}
int main(void){int st,p=0,ed=123804765;scanf("%d",&st);while(findZero(st,p))p++;while(true){dfs(st,p,0,1);if(found){printf("%d\n",D*2-1);break;}dfs(ed,4,0,2);if(found){printf("%d\n",D*2);break;}D++;}return 0;
}

洛谷OJ:P1379 八数码难题(双向搜索)相关推荐

  1. 【洛谷】P1379 八数码难题

    题目地址: https://www.luogu.com.cn/problem/P1379 题目描述: 在3×33×33×3的棋盘上,摆有八个棋子,每个棋子上标有111至888的某一数字.棋盘中留有一个 ...

  2. 洛谷—P1379 八数码难题

    题目链接:P1379 八数码难题 题目大意: 要求最少步骤的移动方法,实现从初始布局到目标布局的转变. 解题思路: 这道题目要用到搜索中比较难的搜索方法-迭代加深的A*算法.所谓迭代加深就是每次限制搜 ...

  3. 洛谷P1379八数码难题

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

  4. [洛谷] P1379 八数码难题( 提高+/省选- )

    八数码 1.题目 2.分析 3.代码 1. bfs (+queue) + unordered_map 重点分析 2.双向bfs (适用于知道起始状态的情况) 思路分析 3.双向bfs优化 思路 4.总 ...

  5. P1379 八数码难题 题解(双向宽搜)

    博客园同步 原题链接 简要题意: 给定一个 3 × 3 3 \times 3 3×3 的矩阵,每次可以把空格旁边(四方向)的一个位置移到空格上.求到目标状态的最小步数. 前置知识: 单向宽搜的写法 O ...

  6. IDA*-洛谷P1379 八数码难题

    https://daniu.luogu.org/problem/show?pid=1379 省选的收获 暗金 学会了A*啦啦啦: 我在第一天学了A*; 然后回家颓废之余思考思考: 又问了van爷一些小 ...

  7. 习题:八数码难题(双向BFS)

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

  8. 【codevs1225】八数码难题,如何精确地搜索

    1225 八数码难题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description Yours和zero在研究A*启发式算法.拿到一道 ...

  9. 利用Python求解八数码难题

    实验目的 实验内容 八数码问题也称为九宫问题.在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同.棋盘上还有一个空格,与空格相邻的棋子可以移到空格中.要求解决的问题 ...

最新文章

  1. vue-cli 官方模板webpack-simple的npm run dev 与npm run bulid的一些问题
  2. 【BZOJ-3262】陌上花开 CDQ分治(3维偏序)
  3. Kaggle常用函数总结 原创 2017年07月03日 21:47:34 标签: kaggle 493 kaggle比赛也参加了好几次,在这里就把自己在做比赛中用到的函数汇总到这,方便自己以后查阅
  4. IO多路复用的三种机制Select,Poll,Epoll
  5. JavaScript | 声明数组并使用数组索引分配元素的代码
  6. 页面常见跳转的方法和选择
  7. LinkedList和 ArrayList的大数据面试资料(面试题)
  8. 海森堡不确定性原理实验
  9. SQL Service安装教程
  10. 小王Java学习打卡day07——模板方法设计,接口,多态
  11. 基于PaddlePaddle 2.0动态图实现的CRNN文字识别模型
  12. CocCocoa Touch框架和Cocoa
  13. 记录Android平铺展开效果属性动画
  14. “一见杨过误终生”,《神雕侠侣》2014年 超清1080P未删节版52集全
  15. 泡一杯清茶,看窗外细细的雨
  16. win10桌面右下角网络图标中找不到网络
  17. python的积木式编程
  18. 服务器微信了早上好,微信早上好祝福语大全
  19. 【DX-BT24蓝牙模块-AT命令与手机透传教程】
  20. MySQL数据库管理工具Navicat与PhpMyAdmin功能对比

热门文章

  1. 2021年中国5G传输网络市场趋势报告、技术动态创新及2027年市场预测
  2. 生活中常见物联网实例_什么是物联网?常见IoT 物联网协议最全讲解
  3. pyhton学习实例demo
  4. 计算机网络 学习指南,计算机网络工程师学习路线指南
  5. 数采仪下生活垃圾焚烧发电厂烟气排放过程(工况)自动监控
  6. 用Java写一个简单的回合制游戏
  7. FPGA入门学习笔记(五)Vivado模块化设计
  8. 红米k40隐私空间进入方法
  9. 红米k40关闭系统自动更新方法介绍(详细步骤)
  10. 【PS/PSD】冬季中国风鸟类水墨写意素材