只有9!=362880个状态,用康托展开hash一下直接bfs即可

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=1000005,fac[]={1,1,2,6,24,120,720,5040,40320,362880},d1[]={4,1,2,7,5,3,8,9,6},d2[]={1,2,3,6,4,5,7,8,9};
int a[15],b[15],v[15],dis[N],la[N],tot;
long long s,t=123456789,ans[N];
int has(long long x)
{
for(int i=9;i>=1;i--)
a[i]=x%10,x/=10;
int r=0;
for(int i=1,sm;i<=9;i++)
{
sm=0;
for(int j=i+1;j<=9;j++)
if(a[j]<a[i])
sm++;
r+=fac[9-i]*sm;
}
return r;
}
long long rel(int x)
{
memset(v,0,sizeof(v));
long long r=0;
for(int i=9;i>=1;i--)
{
int t=x/fac[i-1];
x%=fac[i-1];
for(int j=1,w=0;j<=9;j++)
if(!v[j])
{
w++;
if(w==t+1)
{
r=r*10+j;
v[j]=1;
break;
}
}
}
return r;
}
int main()
{
for(int i=1,x;i<=9;i++)
scanf("%d",&x),s=s*10+x+1;
s=has(s),t=has(t);//cerr<<s<<" "<<t<<" "<<rel(s)<<" "<<rel(t)<<endl;
queue<int>q;
dis[s]=1;
q.push(s);
while(!q.empty())
{
int u=q.front();//cerr<<u<<endl<<rel(u)<<endl;
q.pop();
if(u==t)
break;
long long x=rel(u),v1=0,v2=0;
for(int i=9;i>=1;i--)
a[i]=x%10,x/=10;
for(int i=0;i<9;i++)
v1=v1*10+a[d1[i]],v2=v2*10+a[d2[i]];//cerr<<v1<<" "<<v2<<endl;
v1=has(v1),v2=has(v2);//cerr<<v1<<" "<<v2<<endl;
if(!dis[v1])
la[v1]=u,dis[v1]=dis[u]+1,q.push(v1);
if(!dis[v2])
la[v2]=u,dis[v2]=dis[u]+1,q.push(v2);
}
if(!dis[t])
{
puts("UNSOLVABLE");
return 0;
}
printf("%d\n",dis[t]-1);
for(int i=t;i!=s;i=la[i])
ans[++tot]=rel(i);
ans[++tot]=rel(s);
for(int i=tot;i>=1;i--)
{
for(int j=1;j<=9;j++)
a[j]=ans[i]%10-1,ans[i]/=10;
printf("%d %d %d\n%d %d %d\n%d %d %d\n\n",a[9],a[8],a[7],a[6],a[5],a[4],a[3],a[2],a[1]);
}
return 0;
}

洛谷 P2578 [ZJOI2005]九数码游戏【bfs+康托展开】的更多相关文章

  1. [ZJOI2005]九数码游戏(BFS+hash)

    Solution 这题的话直接上BFS就可以了,因为要输出方案,所以我们要开一个pre数组记录前驱,最后输出就可以了. 对于状态的记录,一般都用哈希来存,但因为这道题比较特殊,它是一个排列,所以我们可 ...

  2. [ZJOI2005]九数码游戏

    [ZJOI2005]九数码游戏 题目描述 输入输出格式 输入格式: 输入文件中包含三行三列九个数,同行的相邻两数用空格隔开,表示初始状态每个方格上的数字.初始状态不会是目标状态. 输出格式: 如果目标 ...

  3. 洛谷 - P2578 - 九数码游戏 - bfs

    https://www.luogu.org/problemnew/show/P2578 一个挺搞的东西,用康托展开做记忆化搜索可以少一个log的查询. #include <bits/stdc++ ...

  4. [洛谷P3014][USACO11FEB]牛线Cow Line (康托展开)(数论)

    如果在阅读本文之前对于康托展开没有了解的同学请戳一下这里:  简陋的博客    百度百科 题目描述 N(1<=N<=20)头牛,编号为1...N,正在与FJ玩一个疯狂的游戏.奶牛会排成一行 ...

  5. LG2578 「ZJOI2005」九数码游戏 bfs

    问题描述 LG2578 题解 用string+map去重. bfs即可. \(\mathrm{Code}\) #include<bits/stdc++.h> using namespace ...

  6. 万圣节后的早晨&&九数码游戏——双向广搜

    https://www.luogu.org/problemnew/show/P1778 https://www.luogu.org/problemnew/show/P2578 双向广搜. 有固定起点终 ...

  7. hdu3567 八数码2(康托展开+多次bfs+预处理)

    Eight II Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 130000/65536 K (Java/Others)Total S ...

  8. HDU_1043 Eight 【逆向BFS + 康托展开 】【A* + 康托展开 】

    一.题目 http://acm.hdu.edu.cn/showproblem.php?pid=1043 二.两种方法 该题很明显,是一个八数码的问题,就是9宫格,里面有一个空格,外加1~8的数字,任意 ...

  9. POJ 1077 Eight (BFS+康托展开)详解

    本题知识点和基本代码来自<算法竞赛 入门到进阶>(作者:罗勇军 郭卫斌) 如有问题欢迎巨巨们提出 题意:八数码问题是在一个3*3的棋盘上放置编号为1~8的方块,其中有一块为控制,与空格相邻 ...

随机推荐

  1. 安卓自己定义View进阶-Canvas之绘制基本形状

    Canvas之绘制基本形状 作者微博: @GcsSloop [本系列相关文章] 在上一篇自己定义View分类与流程中我们了解自己定义View相关的基本知识,只是,这些东西依然还是理论,并不能拿来(zh ...

  2. palindrome-partitioning I&II——回文切割、深度遍历

    I: Given a string s, partition s such that every substring of the partition is a palindrome. Return ...

  3. JAVA设计模式之 原型模式【Prototype Pattern】

    一.概述: 使用原型实例指定创建对象的种类,而且通过拷贝这些原型创建新的对象. 简单的说就是对象的拷贝生成新的对象(对象的克隆),原型模式是一种对象创建型模式. 二.使用场景: 创建新的对象能够通过对 ...

  4. 【转载】图说OOP基础(一)

    本文用图形化的形式描述OOP的相关知识.对OOP进行系统化的梳理,以便掌握. 涉及知识点: OOP的相关知识 OOP知识[Object-Orientation Programming 面向对象编程]总 ...

  5. 网络请求--Retrofit2用法

    欢迎Follow我的GitHub, 关注我的CSDN. Retrofit是Square开发的网络请求库, 简化了网络请求的使用, 这个库太知名了, 优点我就不多说了. 让我们看看怎样使用吧? 注意: ...

  6. Linux安装程序Anaconda分析(续)

    本来想写篇关于Anaconda的文章,但看到这里写的这么详细,转,原文在这里:Linux安装程序Anaconda分析(续) (1) disptach.py: 下面我们看一下Dispatcher类的主要 ...

  7. 不能实现RadioButton默认选择

    当用RadioButton时,希望在程序运行的时候默认一个选项: CheckRadioButton(IDC_RADIO1,IDC_RADIO2,IDC_RADIO1); //CheckRadioBut ...

  8. debian iptables持久化

    1 保存iptables iptables-save > /etc/iptables.rules   2 创建启动文件 touch /etc/network/if-pre-up.d/iptabl ...

  9. sql insert and update

    1 二者的区别 insert是插入一条新的数据,它会创建一条新的记录:update是更新一条已经有的数据,它不会创建新的记录. update需要where来指示更新那条记录,否则会更新所有的记录. 2

  10. Mac开发必备工具(一)—— Homebrew

    Homebrew 简介 macOS 缺失的软件包管理器.使用 Homebrew 安装 Apple 没有预装但 你需要的东西.官网有中文说明. 安装与配置 Homebrew 的安装非常简单,将下面这条命 ...