1.  
  1. 12号到今天共研究八数码问题poj1077,首先用的是普通BFS,遇到很多问题,开始用一个二级指针作为结构成员,知道了二级指针与二维数值名的不同!http://write.blog.csdn.net/postedit!讲得不错。发现自己代码能力渣死!进入正题,用BFS过不了,先学习了八数码问题有解条件,并扩展到N数码有解问题。做到奇数偶数剪枝,过不了,太慢,于是学习了HASH判重,学习了康托展开(排列与数字的一一对应关系),效率大大增加!但是别人这样过了都,我是过不了啊!于是去学双广!没怎么看明白,,,很想放弃了!于是去学习了A*算法!(启发式搜索),46ms,BFS是最普通的A*,那么,我用优先队列优化,设置启发函数,把优先级高的先出队!本质已经破坏了BFS的分层搜索,倒是有点DFS了,我名之为bdfs!,有方向性!这样找一组解很容易!不用遍历所有!

于是去切了骑士问题,先是8格的的,再是n格的,接下!

  1. #include<iostream> //优先(小的优先)队列BFS+hash判重+奇数偶数剪枝
  2. #include<queue>
  3. #include<string>
  4. #include<cstdio>
  5. #include<set>
  6. #include<cstring>
  7. using namespace std;
  8. string a;
  9. int f[4][2]={0,1,0,-1,1,0,-1,0};//方向
  10. bool state[362881];
  11. int fac[10]={1,1,2,6,24,120,720,5040,40320,362880};
  12. struct xy
  13. {
  14. string aa; //当前状态
  15. int x; //空格的坐标
  16. int y;
  17. int abs_to_end; //和目标数相同的方块数目!
  18. string s; // 字符串,保存当前移动情况
  19. bool operator < (const xy & now) const //自定义离目标小的优先!
  20. {
  21. return now.abs_to_end>abs_to_end;
  22. }
  23. };
  24. int get_abs(string aa) //只要第一次获得,其他改变修改
  25. {
  26. int res=0;
  27. for(int i=1;i<=9;i++)
  28. {
  29. if(aa[i]!='9'&&aa[i]==('0'+i))res++;
  30. }
  31. return res;
  32. }
  33.  
  34. bool has_solution() //无解条件,奇偶剪枝!
  35. {
  36. int t[9];int count=0;
  37. for(int i=0;i<3;i++)
  38. for(int j=0;j<3;j++)
  39. t[count++]=a[i*3+j]-'0';
  40. count=0;
  41. for(int i=0;i<9;i++)
  42. for(int j=i+1;j<9;j++)
  43. if(t[j]!=9&&t[i]!=9&&t[j]<t[i])count++;
  44. if(count%2==0)return 1;
  45. return 0;
  46. }
  47. string bfs(int ox,int oy) //
  48. {
  49. priority_queue<xy>q;
  50. xy dian; dian.x=ox;dian.y=oy; //赋初值
  51. dian.s=""; //首地址的赋值,二维数组必先从一维建立。用的还是同一个!
  52.  
  53. for(int i=0;i<3;i++)
  54. {
  55. for(int j=0;j<3;j++)
  56. {
  57. dian.aa+=a[i*3+j];
  58. }
  59. }
  60. dian.abs_to_end=get_abs(dian.aa);
  61. q.push(dian);
  62. if(dian.aa=="123456789")return dian.s;
  63. while(!q.empty())
  64. {
  65. xy temp=q.top();
  66. q.pop(); //取队首拓展
  67. for(int i=0;i<4;i++)
  68. { // xy next=temp;这样只是完全赋值,指针指的是同一块地址!
  69. xy next(temp);
  70. int space=next.x*3+next.y;
  71. next.x=next.x+f[i][0]; //四个方向拓展。
  72. next.y=next.y+f[i][1];
  73. if(next.x>=0&&next.x<3&&next.y>=0&&next.y<3)
  74. {
  75. if(i==0)
  76. {
  77. if(next.s.size()>0&&'l'==next.s[next.s.size()-1])continue;
  78. next.s+="r";
  79. if(next.aa[space+1]=='1'+space+1)next.abs_to_end--;
  80. if(next.aa[space+1]=='1'+space)next.abs_to_end++;
  81. next.aa[space]=next.aa[space+1];
  82. next.aa[space+1]='9';
  83. }
  84. else if(i==1)
  85. {
  86. if(next.s.size()>0&&'r'==next.s[next.s.size()-1])continue;
  87. next.s+="l";
  88. if(next.aa[space-1]=='1'+space-1)next.abs_to_end--;
  89. if(next.aa[space-1]=='1'+space)next.abs_to_end++;
  90. next.aa[space]=next.aa[space-1];
  91. next.aa[space-1]='9';
  92. }
  93. else if(i==2)
  94. {
  95. if(next.s.size()>0&&'u'==next.s[next.s.size()-1])continue;
  96. next.s+="d";
  97. if(next.aa[space+3]=='1'+space+3)next.abs_to_end--;
  98. if(next.aa[space+3]=='1'+space)next.abs_to_end++;
  99. next.aa[space]=next.aa[space+3];
  100. next.aa[space+3]='9';
  101. }
  102. else if(i==3)
  103. {
  104. if(next.s.size()>0&&'d'==next.s[next.s.size()-1])continue;
  105. next.s+="u";
  106. if(next.aa[space-3]=='1'+space-3)next.abs_to_end--;
  107. if(next.aa[space-3]=='1'+space)next.abs_to_end++;
  108. next.aa[space]=next.aa[space-3];
  109. next.aa[space-3]='9';
  110. }
  111. if(next.aa=="123456789")return next.s;
  112. string ts=next.aa; //int hash(string ts)
  113. int res=0;
  114. for(int i=0;i<9;i++)
  115. {
  116. int count=0;
  117. for(int j=i+1;j<9;j++)
  118. if(ts[j]<ts[i])count++;
  119. res+=count*fac[9-i-1];
  120. }
  121. if(state[res])continue;
  122. state[res]=true;
  123. q.push(next);
  124. }
  125. }
  126. }
  127. }
  128. int main()
  129. {
  130. string ta;
  131. while(getline(cin,ta))
  132. {
  133. int ox,oy;
  134. a.clear();
  135. for(int i=0;i<ta.size();i++)
  136. {
  137. if(ta[i]=='x') a+='9';
  138. else if(ta[i]!=' ')a+=ta[i];
  139. }
  140. for(int i=0;i<a.size();i++)
  141. {
  142. if(a[i]=='9'){ox=i/3;oy=i%3;}
  143. }
  144. memset(state,0,sizeof(state));
  145. if(!has_solution())cout<<"unsolvable"<<endl;
  146. else
  147. {
  148. cout<<bfs(ox,oy)<<endl;
  149. }
  150. }
  151. return 0;
  152. }

由八数码问题引入。对BFS有更深考虑的更多相关文章

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

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

  2. HDU-1043 Eight八数码 搜索问题(bfs+hash 打表 IDA* 等)

    题目链接 https://vjudge.net/problem/HDU-1043 经典的八数码问题,学过算法的老哥都会拿它练搜索 题意: 给出每行一组的数据,每组数据代表3*3的八数码表,要求程序复原 ...

  3. hdu1043Eight (经典的八数码)(康托展开+BFS)

    建议先学会用康托展开:http://blog.csdn.net/u010372095/article/details/9904497 Problem Description The 15-puzzle ...

  4. Eight(South Central USA 1998)(八数码) 分类: bfs 2015-07-05 22:34 1人阅读 评论(0) 收藏

    The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've see ...

  5. 【洛谷P1379】八数码难题 状压bfs

    对于这道题来说,每个时刻的状态是整个棋盘所有棋子的位置,即:任何一个棋子位置发生了移动,都会使得状态转移. 因此,需要采取将整个状态作为广搜的搜索对象,进行状态压缩.采用哈希得到每个状态的对应的数值, ...

  6. 洛谷 P1379 八数码难题(map && 双向bfs)

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

  7. BFS(八数码) POJ 1077 || HDOJ 1043 Eight

    题目传送门1 2 题意:从无序到有序移动的方案,即最后成1 2 3 4 5 6 7 8 0 分析:八数码经典问题.POJ是一次,HDOJ是多次.因为康托展开还不会,也写不了什么,HDOJ需要从最后的状 ...

  8. UVALive 6665 Dragon’s Cruller --BFS,类八数码问题

    题意大概就是八数码问题,只不过把空格的移动方式改变了:空格能够向前或向后移动一格或三格(循环的). 分析:其实跟八数码问题差不多,用康托展开记录状态,bfs即可. 代码: #include <i ...

  9. [cdoj1380] Xiper的奇妙历险(3) (八数码问题 bfs + 预处理)

    快要NOIP 2016 了,现在已经停课集训了.计划用10天来复习以前学习过的所有内容.首先就是搜索. 八数码是一道很经典的搜索题,普通的bfs就可求出.为了优化效率,我曾经用过康托展开来优化空间,甚 ...

随机推荐

  1. vmware桥接模式下主机有多个网卡导致虚拟机网络不通

    桥接模式下,vmware会绑定一个物理网卡,因此有多个物理网卡时就要注意当前绑定的物理网卡.打开如下vmware菜单 可以看到VMnet0是桥接模式用的,然后他可以选择绑定一个物理网卡,注意要正确选择 ...

  2. CPP-STL:list容器

    本文以List容器为例子,介绍了STL的基本内容,从容器到迭代器,再到普通函数,而且例子丰富,通俗易懂.不失为STL的入门文章,新手不容错过! 目录 1 定义一个list 2 使用list的成员函数p ...

  3. No-1.文件和目录

    文件和目录 01. 单用户操作系统和多用户操作系统(科普) 单用户操作系统:指一台计算机在同一时间 只能由一个用户 使用,一个用户独自享用系统的全部硬件和软件资源 Windows XP 之前的版本都是 ...

  4. 第4节 hive调优:2、数据倾斜

    数据的倾斜: 主要就是合理的控制我们的map个数以及reduce个数 第一个问题:maptask的个数怎么定的???与我们文件的block块相关,默认一个block块就是对应一个maptask 第二个 ...

  5. My Friends

    HMQ's blog RMY's blog Shq's blog wjyyy‘s blog

  6. ubuntu中执行docker info出现警告信息WARNING: No memory limit support 或 WARNING: No swap limit support

    docker info 指令报若下错误:WARNING: No memory limit support 或WARNING: No swap limit support 解决方法: 1.打开/etc/ ...

  7. (16) Cloudflare pki公钥基础设施

    该工具组共有8个工具 1.cfssl 常用的可用指令: sign signs a certificate bundle build a certificate bundle genkey genera ...

  8. 在不使用ssr的情况下解决Vue单页面SEO问题

    遇到的问题: 近来在写个人博客的时候遇到了大家可能都会遇到的问题 Vue单页面在SEO时显得很无力,尤其是百度不会抓取动态脚本 Vue-Router配合前后端分离无法让meta标签在蜘蛛抓取时动态填充 ...

  9. CSS3---渲染属性

    1.计数器 CSS3计数器( CSS Counters )可以允许我们使用css对页面中的任意元素进行计数,实现类似于有序列表的功能.与有序列表相比,它的突出特性在于可以对任意元素计数,同时实现个性化 ...

  10. Postfix telnet www.azengna.com 25 Connection Refused 但是localhost连接成功

    修改配置文件 vi /etc/postfix/main.cf 原先配置信息 .... inet_interfaces = all #inet_interfaces = $myhostname,loca ...