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. Linux 用户 和 组 快速了解

    1用户 (Linux中“只有超级管理员”才有权限操作 用户 和组) 1.1添加用户 useradd 命令 例如 :useradd hly //添加了一个新账户 hly 用户添加后 会存放在一个文件中, ...

  2. zookeeper相关知识与集群搭建

    Zookeeper Zookeeper相关概念 Zookeeper概述 Zookeeper是一个分布式协调服务的开源框架,主要用来解决分布式集群中应用系统的一致性问题. Zookeeper本质上是一个 ...

  3. python应用:经纬度匹配

    需要安装第三方包:requests 本次经纬度匹配采用高德地图api,首先将gps坐标转化为高德地图的经纬度坐标,然后再根据转化后的坐标进行匹配. 本次匹配主要是获取距离给定经纬度最近的poi点地址信 ...

  4. shell重温---基础篇(printf命令&test命令)

    在shell中还有一个输出的命令,那就是printf了.它模仿的是C程序库(library)里的printf()程序,是由POSIX标准所定义,所以嘞,使用printf脚本比echo移植性要好一点,它 ...

  5. CentOS 7 systemd添加自定义系统服务

    systemd: CentOS 7的服务systemctl脚本存放在:/usr/lib/systemd/,有系统(system)和用户(user)之分,即:/usr/lib/systemd/syste ...

  6. 洛谷P1364 医院设置

    LITTLESUN的第一道图论,撒花~~ 题目链接 这道题是Floyd的板子题 注意对于矩阵图的初始值赋值要全部赋值成最大值 十六进制的最大值表示方式是0x3f3f3f3f memset(G,0x3f ...

  7. 区分Oracle的数据库,实例,服务名,SID

    文章摘自:http://www.zhetao.com/content240 感谢分享O(∩_∩)O~ 在实际的开发应用中,关于Oracle数据库,经常听见有人说建立一个数据库,建立一个Instance ...

  8. python语法图

  9. "Cannot open source file "Wire.h" " in Arduino Development

    0. Environment Windows 8 x64 Arduino 1.0.5 Visual studio 2012 Visual micro Arduino 1. Steps Add &quo ...

  10. cf#513 B. Maximum Sum of Digits

    B. Maximum Sum of Digits time limit per test 2 seconds memory limit per test 512 megabytes input sta ...