[八数码][1]

[1]: https://www.luogu.org/problem/show?pid=1379

其实除了搜索恶心一点,好像也没什么提高+的

bfs搜的是状态。

双向bfs同时从起点(初始状态)和终点(最终状态)开始搜。当两边搜到同样的状态说明出结果了。因为bfs是一层层搜的,所以最早搜到同样状态就是最优解。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<string>
#include<set>
#include<queue>
#include<vector>
using namespace std;
struct str
{
string s;//当前状态字符串
int posi;//当前状态0的位置
};
int fangxiang[]={-3,+1,+3,-1};//up right down left
//fangxiang[]预先储存好各个方向的运算数,直接把0的位置加上去就好
set <string> m1,m2;//set判断这个状态是否已经有了
queue <str> q1,q2;//queue是枚举的状态
int c,c1=1,c2=1,cc;//c为循环边界(由c1,c2)获得,c1是上次bfs得来的本次bfs的状态数
int bfs()
{
while(!q1.empty())
{
cc++;
str t,x;
//zheng
c=c1;
c1=0;
while(c--)
{
t=q1.front();
q1.pop();
for(int j=0;j<4;j++)
{
x=t;
//看下面,都差不多的
if(j==0 and t.posi<3)
continue;
if(j==1 and t.posi%3==2)
continue;
if(j==2 and t.posi>5)
continue;
if(j==3 and t.posi%3==0)
continue;
swap(x.s[x.posi],x.s[x.posi+fangxiang[j]]);
x.posi+=fangxiang[j];
if(m1.count(x.s))
continue;
q1.push(x);
c1++;
m1.insert(x.s);
if(m2.count(x.s))
return cc*2-1;
}
}
//fan
c=c2;
c2=0;
for(int i=0;i<c;i++)
{
t=q2.front();//取出队首,进行bfs
q2.pop();
for(int j=0;j<4;j++)
{
x=t;
//需要枚举4个方向,所以用个x
if(j==0 and t.posi<3)
continue;
if(j==1 and t.posi%3==2)
continue;
if(j==2 and t.posi>5)
continue;
if(j==3 and t.posi%3==0)
continue;
//限制条件
swap(x.s[x.posi],x.s[x.posi+fangxiang[j]]);//移动0
x.posi+=fangxiang[j];
if(m2.count(x.s))
continue;
q2.push(x);
c2++;
m2.insert(x.s);
if(m1.count(x.s))
return cc*2;
}
}
}
return 0;
}
int main()
{
//freopen("4.in","r",stdin);
ios::sync_with_stdio(false);
str ed=(str){"123804765",4};
str st;
cin>>st.s;
st.posi=st.s.find('0');
q1.push(st);
q2.push(ed);
m1.insert(st.s);
m2.insert(ed.s);
if(st.s==ed.s)//如果起始和终止相同,那太好了根本不用移!
{
cout<<"0";
return 0;
}
cout<<bfs();
return 0;
}

双向bfs-八数码问题的更多相关文章

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

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

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

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

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

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

  4. 双向广搜+hash+康托展开 codevs 1225 八数码难题

    codevs 1225 八数码难题  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond   题目描述 Description Yours和zero在研究A*启 ...

  5. 【双向广搜+逆序数优化】【HDU1043】【八数码】

    HDU上的八数码 数据强的一B 首先:双向广搜 先处理正向搜索,再处理反向搜索,直至中途相遇 visit 和 队列都是独立的. 可以用一个过程来完成这2个操作,减少代码量.(一般还要个深度数组) 优化 ...

  6. HDU1043 八数码(BFS + 打表)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 , 康托展开 + BFS + 打表. 经典八数码问题,传说此题不做人生不完整,关于八数码的八境界 ...

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

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

  8. luoguP1379-八数码难题(双向bfs)

    题目链接:https://www.luogu.org/problemnew/show/P1379 题意:用字符串表示八数码,求根据给定八数码得到末状态“123804765”最少的步数. 思路:这题很方 ...

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

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

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

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

随机推荐

  1. myeclipse自动保存修改代码

    当你修改过代码后,myeclipse往往要你手动的保存代码才能运行这个修改后的代码,要是不保存就会一直运行修改前的代码.只要修改myeclipse中这两项,就可以让它编译运行修改后的代码: Windo ...

  2. html2cavans

    简介:http://www.jianshu.com/p/6a07e974a7e8 下载:https://github.com/niklasvh/html2canvas/releases C#代理git ...

  3. jQuery选择器(子元素过滤选择器)第七节

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...

  4. Python丨Python 性能分析大全

    虽然运行速度慢是 Python 与生俱来的特点,大多数时候我们用 Python 就意味着放弃对性能的追求.但是,就算是用纯 Python 完成同一个任务,老手写出来的代码可能会比菜鸟写的代码块几倍,甚 ...

  5. CentOS6.8系统下,ecipse下进行编辑操作,意外退出

    错误情况:centos下打开eclipse软件,点击*.java或者*.pom软件卡死,命令行终端报错误信息,稍后eclipse自动退出. 错误信息: Java: cairo-misc.c:380: ...

  6. 百度统计的JS脚本原理分析

    首先,百度统计会要求我们在要统计的页面中嵌入一段js语句,类似如下: <script type="text/javascript">var _bdhmProtocol ...

  7. git如何忽略文件

    偶尔有一些文件你不想让git提交到代码配置库上,这里有一些方法可以告诉git,有哪些文件可以忽略. 创建一个本地的.gitignore 如果你在你的git库(repository)中创建了一个名为.g ...

  8. Python之多进程篇

    Process 创建子进程执行指定的函数 >>> from multiprocessing import Process,current_process >>> & ...

  9. 激光相机数据融合(5)--Gazebo仿真数据融合

    这一节将用ROS+Gazebo 环境获取激光获取点云,并用PCL和OPENCV处理,源代码在:https://github.com/ZouCheng321/5_laser_camera_sim 由于激 ...

  10. swizzle method 和消息转发机制的实际使用

    我的工程结构,如图 1-0 图  1-0 在看具体实现以前,先捋以下 实现思路. ViewController 中有一个-(void)Amethod;A方法. -(void)Amethod{ NSLo ...