P1379 八数码难题

题目描述

在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。

输入输出格式

输入格式:

输入初始状态,一行九个数字,空格用0表示

输出格式:

只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊无法到达目标状态数据)


虽然这个题没有用到,但还是提一下有解性判断

当棋盘长度是奇数时,有解等价于初始状态与目标状态的抽出来横着放的序列中逆序对个数的奇偶性相同

正常的解题思路:

用康托展开判重,用曼哈顿距离估价搜索

然而我最开始打的记搜wa的不行

最后终于想明白,有环记搜个锤子啊!!!

事实上状态量很少,直接广搜就可以


Code:

#include <cstdio>
#include <cstring>
const int N=1e6;
int s[10],fac[10],step[N],used[N],l,r;
int a[10]={0,2,3,4,9,1,5,8,7,6};
void add(int x){while(x<=9) ++s[x],x+=x&-x;}
int ask(int x){int su=0;while(x) su+=s[x],x-=x&-x;return su;}
struct node
{
int a[10];
}q[N];
int kanton(node x)
{
int ans=0;memset(s,0,sizeof(s));
for(int i=1;i<=9;i++)
ans+=fac[9-i]*(x.a[i]-1-ask(x.a[i])),add(x.a[i]);
return ans;
}
void swap(int &x,int &y){int tmp=x;x=y,y=tmp;}
int main()
{
fac[0]=1;node s;
for(int i=1;i<=9;i++) fac[i]=fac[i-1]*i,s.a[i]=a[i];
int to=kanton(s);
char c[10];scanf("%s",c+1);
for(int i=1;i<=9;i++) s.a[i]=c[i]-'0'+1;
q[0]=s;step[0]=0;
while(l<=r)
{
node now=q[l++];
int id=kanton(now),pos;
if(id==to) {printf("%d\n",step[l-1]);break;}
if(used[id]) continue;used[id]=1;
for(int i=1;i<=9;i++) if(now.a[i]==1) {pos=i;break;}
if(pos%3!=1)
{
node t=now;
swap(t.a[pos],t.a[pos-1]);
q[++r]=t,step[r]=step[l-1]+1;
}
if(pos%3)
{
node t=now;
swap(t.a[pos],t.a[pos+1]);
q[++r]=t,step[r]=step[l-1]+1;
}
if(pos>3)
{
node t=now;
swap(t.a[pos],t.a[pos-3]);
q[++r]=t,step[r]=step[l-1]+1;
}
if(pos<7)
{
node t=now;
swap(t.a[pos],t.a[pos+3]);
q[++r]=t,step[r]=step[l-1]+1;
}
}
return 0;
}

2018.8.30

洛谷 P1379 八数码难题 解题报告的更多相关文章

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

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

  2. 洛谷P1379八数码难题

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

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

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

  4. 洛谷 P1379 八数码难题

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

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

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

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

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

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

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

  8. 洛谷P1379 八数码难题

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

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

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

随机推荐

  1. 构造HTTP请求Header实现“伪造来源IP”

    在阅读本文前,大家要有一个概念,在实现正常的TCP/IP 双方通信情况下,是无法伪造来源 IP 的,也就是说,在 TCP/IP 协议中,可以伪造数据包来源 IP ,但这会让发送出去的数据包有去无回,无 ...

  2. thinkphp phpmailer邮箱验证

    thinkphp 关于phpmailer的邮箱验证 一  . 登陆自己的邮箱,例如:qq邮箱.登陆qq邮箱在账户设置中开启smtp服务: 之后回发送一个授权码 , 这个授权码先保存下来,这个授权码在后 ...

  3. python 中 pynlpir错误 Cannot Open Configure file pynlpir\Data\Configure.xml 解决

    在用python做分词.数据处理的时候,想调用pynlpir库,pynlpir.open()时出现错误,更新一下授权文件还是错误, 仔细一看错误是:Cannot Open Configure file ...

  4. 网络基础,tpc,udp

    一 , 网络基础相关知识 1. 架构 (重点) C / S  架构 : client 客户端(APP) 和 server 服务器端 能充分发挥pc机的性能 B / S 架构 : browser 浏览器 ...

  5. 「LibreOJ#515」贪心只能过样例 (暴力+bitset)

    可以发现,答案最大值只有106,于是想到用暴力维护 可以用bitset合并方案可以优化复杂度, Code #include <cstdio> #include <bitset> ...

  6. 第5模块闯关Bootstrap

    “行(row)”必须包含在 .container (固定宽度)或 .container-fluid (100% 宽度)中,以便为其赋予合适的排列(aligment)和内补(padding). 通过“行 ...

  7. 【好帖】 Mark

    1. 管理篇 2. 程序员选择公司的8个标准 3. 实用工具 4. 离职跳槽 5. DBA 6. 做一个网站多少钱? 7. 十大算法 8. 寻求用户评价App的正确方法 9. 工程师忽略的隐形成本 1 ...

  8. 【连载】Maven系列(三) 进阶

    相关文章: 1.<用起来超爽的Maven——入门篇> 2.<用起来超爽的Maven——进阶篇> 一.Maven坐标: Maven世界拥有大量需要构建jar文件,我们需要找一个用 ...

  9. fiddler抓包工具的基本使用

    fiddler是基于C#的HTTP抓包工具. fiddler的原理: fiddler是http代理服务器,它会抓取浏览器向服务器发送的HTTP请求,然后在将该请求发送到服务器.再获取从服务器返回的请求 ...

  10. Qt Qwdget 汽车仪表知识点拆解1 速度表示

    先贴上效果图,注意,没有写逻辑,所以这些都是乱动的 这里线主要说一下中间显示速度的显示制作的方式,在这里,自己专门写了一个数字的仪表 考虑的一般的汽车是没有办法把瞬时速度提升到四位数的,所以我这里就放 ...