题目传送门

解题思路:

一道bfs,本题最难的一点就是如何储存已经被访问过的状态,如果直接开一个bool数组,空间肯定会炸,所以我们要用另一个数据结构存,STL大法好,用map来存,直接AC.

AC代码:

  1. #include<cstdio>
  2. #include<iostream>
  3. #include<map>
  4. #include<queue>
  5.  
  6. using namespace std;
  7.  
  8. int a[][],n;
  9. int ans = ;
  10. const int dx[]={-,,,},dy[]={,-,,};
  11. map<int,int> m;
  12.  
  13. inline void bfs() {
  14. queue<long long> q;
  15. q.push(n);
  16. m[n] = ;
  17. while(!q.empty()) {
  18. int u = q.front();
  19. q.pop();
  20. int x = ,y= ,n = u;
  21. if(u == ans) break;
  22. for(int i = ;i >= ; i--)
  23. for(int j = ;j >= ; j--) {
  24. a[i][j] = n % ;
  25. n /= ;
  26. if(!a[i][j]) x = i,y = j;
  27. }
  28. for(int i = ;i < ; i++) {
  29. int nx = x + dx[i],ny = y + dy[i],ns = ;
  30. if(nx < || ny < || nx > || ny > ) continue;
  31. swap(a[nx][ny],a[x][y]);
  32. for(int i = ;i <= ; i++)
  33. for(int j = ;j <= ; j++)
  34. ns = ns * + a[i][j];
  35. if(!m.count(ns)) {
  36. m[ns] = m[u] + ;
  37. q.push(ns);
  38. }
  39. swap(a[nx][ny],a[x][y]);
  40. }
  41. }
  42. }
  43.  
  44. int main()
  45. {
  46. scanf("%d",&n);
  47. bfs();
  48. printf("%d",m[]);
  49. return ;
  50. }

普通bfs

emmm,虽然普通bfs能A,但还是感觉太慢,所以试了一下双向bfs.

  1. #include<cstdio>
  2. #include<iostream>
  3. #include<queue>
  4. #include<map>
  5.  
  6. using namespace std;
  7.  
  8. int a[][],n,n1 = ;
  9. int x,y;
  10. int wayx[] = {,-,,},wayy[] = {,,,-};
  11. map<int,int> p,sum;
  12.  
  13. inline void juzhen(int o) {
  14. for(int i = ;i >= ; i--)
  15. for(int j = ;j >= ; j--) {
  16. a[i][j] = o % ;
  17. o /= ;
  18. if(a[i][j] == ) x = i,y = j;
  19. }
  20. }
  21.  
  22. inline void double_bfs() {
  23. if(n1 == ) return ;
  24. queue<int> step[];
  25. step[].push(n);
  26. step[].push(n1);
  27. sum[n] = ;
  28. sum[n1] = ;
  29. p[n] = ;p[n1] = ;
  30. int deep = ,s;
  31. while(!step[].empty() || !step[].empty()) {
  32. int i = ;
  33. while(i < ) {
  34. if(sum[step[i].front()] != deep) {
  35. i++;
  36. continue;
  37. }
  38. s = step[i].front();
  39. step[i].pop();
  40. juzhen(s);
  41. for(int w = ;w < ; w++) {
  42. int xx = x + wayx[w];
  43. int yy = y + wayy[w];
  44. if(xx < || xx > || yy < || yy > ) continue;
  45. swap(a[x][y],a[xx][yy]);
  46. int pp = ;
  47. for(int j = ;j <= ; j++)
  48. for(int u = ;u <= ; u++)
  49. pp = pp * + a[j][u];
  50. if(p.count(pp)) {
  51. if(p[pp] == - i) {
  52. if(p[pp] == )
  53. printf("%d",(deep + ) * );
  54. else
  55. printf("%d",deep * + );
  56. return ;
  57. }
  58. }
  59. else {
  60. step[i].push(pp);
  61. sum[pp] = sum[s] + ;
  62. p[pp] = i;
  63. }
  64. swap(a[x][y],a[xx][yy]);
  65. }
  66. }
  67. deep++;
  68. }
  69. }
  70.  
  71. inline void tepan() {
  72. if(n == n1) printf("");
  73. if(n == n1) n = n1 = ;
  74. }
  75.  
  76. int main()
  77. {
  78. scanf("%d",&n);
  79. tepan();
  80. double_bfs();
  81. return ;
  82. }

双向bfs

双向bfs确实快很多很多,普通bfs耗时7.38s,而双向bfs只耗时291ms,快了25倍!!!!!!

洛谷 P1379 八数码难题(map && 双向bfs)的更多相关文章

  1. 洛谷——P1379 八数码难题

    P1379 八数码难题 双向BFS 原来双向BFS是这样的:终止状态与起始状态同时入队,进行搜索,只不过状态标记不一样而已,本题状态使用map来存储 #include<iostream> ...

  2. 洛谷 P1379 八数码难题 解题报告

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

  3. 洛谷P1379八数码难题

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

  4. 洛谷 P1379 八数码难题 Label:判重&&bfs

    特别声明:紫书上抄来的代码,详见P198 题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给 ...

  5. 洛谷P1379 八数码难题

    传送门 1.先用dfs枚举9!的全排列,存到hash数组里(类似离散化),因为顺序枚举,就不需要排序了 2.朴素bfs,判重就用二分找hash:如果发现当前状态=要求状态,输出步数结束程序 上代码 # ...

  6. 洛谷—— P1379 八数码难题

    https://daniu.luogu.org/problem/show?pid=1379 题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示 ...

  7. 洛谷 P1379 八数码难题

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

  8. 洛谷 - P1379 - 八数码难题 - bfs

    https://www.luogu.org/problemnew/show/P1379 #include <bits/stdc++.h> using namespace std; #def ...

  9. 洛谷 P1379 八数码难题 题解

    我个人感觉就是一道bfs的变形,还是对bfs掌握不好的人有一定难度. 本题思路: 大体上用bfs搜,用map来去重,在这里只需要一个队列,因为需要较少步数达到的状态一定在步数较多的状态之前入队列. # ...

随机推荐

  1. Linux学习《第四章脚本》20200222

  2. JS - n次方计算

    pow 方法返回底表达式的指定次幂. Math.pow(base, exponent)  参数base 必选项.表达式底的值. exponent 必选项.表达式的指数值.

  3. 留学论文Results部分英文写作句型整理

    本文分享曼切斯特大学全校语言项目负责人约翰·莫莱博士(Dr John Morley)给出的与结果介绍相关的句型,小编为大家整理了一下一共分为了11类,看完之后觉得非常有用,这里分享给大家,各位留学小伙 ...

  4. 二、【未来】React环境安装:npx

    搭建React的开发环境的第二种方法(新-未来推荐): https://reactjs.org/docs/create-a-new-react-app.html 一. npx简介: 1. npm v5 ...

  5. spring源码 继承AttributeAccessor的BeanDefinition接口

    /** * A BeanDefinition describes a bean instance, which has property values, * constructor argument ...

  6. 第一部分 JavaScript语言核心(三)

    第六章 对象 P123 在ES3中,点运算符后的标识符不能是保留字.如果一个对象的属性名是保留字,name必须使用方括号的形式访问它们,如o["for"]和o["clas ...

  7. office(CVE-2012-0158)漏洞分析报告

    2019/9/12 1.漏洞复现 ①发现崩溃 ②找到漏洞所在的函数,下断点,重新跑起来,单步调试,找到栈被改写的地方 ③分析该函数 把MSCOMCTL拖入IDA,查看该函数代码 ④查看调用栈,回溯. ...

  8. Tornado中的Cookie设置

    Tornado中的cookie分为两种--普通cookie和安全cookie 普通cookie 1.创建cookie 原型 self.set_cookie(name, value, domain=No ...

  9. sqlserver 联接查询的一些注意点

    1.内连接的安全性 (1) inner join 是ANSI SQL-92 语法.等值联接是ANSI SQL-89 的语法 ,两者已相同方式解释.在性能上没有差别 (2)但是强烈建议使用ANSI SQ ...

  10. Win7 node多版本管理gnvm采坑记录

    采坑描述:下载新node版本及切换node失败 解决:1.要用管理员权限启动cmd:2.确保node是空闲的 Gnvm下载地址: 32-bit | 64-bit Github 1.下载之后为 得到一个 ...