[八数码][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. C++ 空间配置器(allocator)

    C++ 空间配置器(allocator) 在STL中,Memory Allocator 处于最底层的位置,为一切的 Container 提供存储服务,是一切其他组件的基石.对于一般使用 STL 的用户 ...

  2. Catch him

    Problem Description 在美式足球中,四分卫负责指挥整只球队的进攻战术和跑位,以及给接球员传球的任务.四分卫是一只球队进攻组最重要的球员,而且一般身体都相对比较弱小,所以通常球队会安排 ...

  3. js 时间字符串转化为时间

    对于时间字符串格式为:"2017-03-03 12:23:55"; IE:显示无效的日期 new Date("2017-03-3 12:23:55") //[d ...

  4. .NET读取Excel文件的三种方法的区别

    ASP.NET读取Excel文件方法一:采用OleDB读取Excel文件: 把Excel文件当做一个数据源来进行数据的读取操作,实例如下: public DataSet ExcelToDS(strin ...

  5. Python 简单的天气预报

    轻巧的树莓派一直是大家的热爱,在上面开发一些小东西让我们很有成就感,而在linux下,python能使麻烦的操作变得简单,而树莓派功耗还很低,相结合,完美! 1,直接进入正题,一般在linux或树莓派 ...

  6. Python之多进程篇

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

  7. SSH框架基础

    首先,SSH不是一个框架,而是多个框架(struts+spring+hibernate)的集成,是目前较流行的一种Web应用程序开源集成框架,用于构建灵活.易于扩展的多层Web应用程序. 集成SSH框 ...

  8. osap一站式分析模型

    运营系统分析平台技术设计: 项目定义于运营系统关键指标的数据分析 关键代码描述: HiveWriter 主要用于写hive表抽象,包括加分区,写hive表,写success文件: import org ...

  9. Vuejs-组件-<slot> 标签分发内容

    资料来自:https://cn.vuejs.org/v2/guide/components.html#具名-Slot 在官方文档的基础上,更加细致的讲解代码. <slot> 标签中的任何内 ...

  10. tpshop使用自带极光推送

    推送逻辑在common里面的PushLogic.php;在后台网站->商城设置->推送设置,将极光的ID,密码填一下系统会自动加入数据库里面. 在你所需推送的PHP类里面引用这个文件即可. ...