[八数码][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. .md即markdown文件的基本常用编写语法

    因为现在的前端基本上都用上了前端构建工具,那就难免要写一些readme等等的说明性文件,但是这样的文件一般都是.md的文件,编写的语法自然跟其他格式的文件有所区别,本文也是我学习写markdown文件 ...

  2. 一个“”字引发的痛苦经历

    (一篇老文章,还有点价值,特意整理了一下.由于涉及客户项目,已经进行了脱敏处理) 1 写在前面的话 虽然这个问题是有解决方案的,但我不建议大家提供给客户,理由见此. 2 问题描述 2010.10.12 ...

  3. Java线程面试题

     1:什么是线程?    线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器编程,你可以使用多线程对运算密集型任务提速.比如,如果一个线 ...

  4. java实现网络爬虫

    import java.io.IOException;   import java.util.HashSet;   import java.util.Set;   import java.util.r ...

  5. linux操作系统基础篇(一)

    1.什么是linux? Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户.多任务.支持多线程和多CPU的操作系统.它能运行主要的UNIX工具软件.应用程序 ...

  6. MacOS 下安装mysqlclient 的问题及解决办法

    [操作环境] 操作系统:MacOS X 10.13.1 mysql运行环境:Docker Docker版本:17.09-ce 在开发Django时,刚开始使用的sqlite进行开发,想部署到生产环境需 ...

  7. UWP更改标题栏颜色

    你是否因为UWP标题栏太丑而想过改变?那么这篇文章或许可以帮助你美化UWP界面,让你的UWP的标题栏也变好看 这里的代码,都要在MainPage的构造函数中.如果你在App类中更改了首页,则在该首页的 ...

  8. ASP.NET Core教程【一】关于Razor Page的知识

    关键文件和目录结构 按照asp.net core WEB应用程序向导,创建一个工程之后 你会发现如下几个目录和文件 wwwroot:放置网站的静态文件的目录 Pages:放置razor页面的目录 ap ...

  9. Android Weekly Notes Issue #284

    November 19th, 2017 Android Weekly Issue #284 本期内容丰富.有趣的有如何搭建真机测试平台,Proguard里面各类keep的区别,如何运行时获得泛型类型, ...

  10. NodeMCU Builder, yet another NodeMCU IDE

    最近几天研究基于NodeMCU的Wi-Fi小车,突然之间想要写一个专门开发NodeMCU Lua代码的工具自己用,由于官方已经有了NodeMCU Studio,所以我的就叫NodeMCU Builde ...