思路:相信不少小伙伴上来就是暴力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. 公共基因表达数据分析系统genevestigator,再也不愁表达数据的查询和比较了
  2. 【工具类】加密工具---MD5使用
  3. TikTok英国市场你不能不知道的10大数据
  4. NYOJ 士兵杀敌(二) 树状数组
  5. Consul-template+nginx实现自动负载均衡
  6. String、StringBuilder、StringBuffer三者执行效率
  7. zigbee是什么,为什么说它最适合智能家居设备
  8. HttpModules 管道过滤 自定义页面
  9. .NET三种异步模式(APM、EAP、TAP)
  10. Re-attention机制Transformer,实现强大性能
  11. java执行python脚本并传递参数_从Java执行Python脚本存在参数传递问题
  12. android如何调用dotnet编写的webservice
  13. 中国地图里暗藏的天机
  14. Check Exception or Uncheck Exception
  15. Linux嵌入式开发入门(一)——初探嵌入式开发板的基本使用
  16. 页面性能优化办法有哪些?
  17. 线速度与角速度的关系
  18. 阿里巴巴今晚发布财报 2019财年全年业绩也将一并公布
  19. ACM SIGIR 2022 | 美团技术团队精选论文解读
  20. 追觅、戴森、小狗吸尘器,谁的性价比最高

热门文章

  1. 【QQ音乐Api】移花接木 打造自己的音乐电台
  2. 错误:ASan runtime does not come first in initial library list; you should either link runtime to
  3. Bootstrap之翻页
  4. 三、redis数据存储之跳跃表(SKIP LIST)
  5. 物联网五大应用实例,一看便明了!!
  6. 【数据结构】求以孩子兄弟表示法存储的森林的叶子结点数,树高
  7. 软件测试--软件测试模型:V模型和W模型
  8. 关于python桑葚图的一些实现
  9. ICCV 2021 | 多模态视频分析与推理比赛来了!行为识别、Re-ID、VQA等四项子任务...
  10. VUE 页面禁止缩放