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

Solution
这题的话直接上BFS就可以了,因为要输出方案,所以我们要开一个pre数组记录前驱,最后输出就可以了。
对于状态的记录,一般都用哈希来存,但因为这道题比较特殊,它是一个排列,所以我们可以利用康拓展开把空间压到9!。
康拓展开
一个排列的康拓展开表示的是字典序比他小的排列的个数,所以我们统计一下每一位后面有几个比它小的数字,乘上(n-i)!
inline int zx_hash(int x){
for(int i=;i>=;--i)a[i]=x%,x/=;
int num=;
for(int i=;i<=;++i){
int aa=;
for(int j=i+;j<=;++j)if(a[i]>a[j])aa++;
num+=aa*jie[-i];
}
return num;
}
逆康拓展开
我们不但要支持把排列映射成数字,还要支持把数字映射成排列。
具体操作就是从高到低按位考虑,令x=num/(n-i)!,那么可选集合中有x个数是比这一位上的数字小的,所以我们选择第x+1个数。
inline int anti_hash(int x){
int num=;
for(int i=;i<=;++i)vec[i]=i;int zo=;
for(int i=;i>=;--i){
int y=x/jie[i];
x=x%jie[i];
num=num*+vec[y];
for(int j=y;j<zo;++j)vec[j]=vec[j+];zo--;
}
return num;
}
不过康拓展开的复杂度是n^2的,但常数较小,遇到哈希排列之类的问题试一下。
Code
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<algorithm>
#define mm make_pair
#define N 12
using namespace std;
const int r1[]={,,,,,,,,,};
const int r2[]={,,,,,,,,,};
int jie[N],a[N],d1[N],d2[N],x,win,ans[],ji[],tag,tot,vec[];
struct node{
int first,second;
};
queue<node>q;
inline int zx_hash(int x){
for(int i=;i>=;--i)a[i]=x%,x/=;
int num=;
for(int i=;i<=;++i){
int aa=;
for(int j=i+;j<=;++j)if(a[i]>a[j])aa++;
num+=aa*jie[-i];
}
return num;
}
inline int anti_hash(int x){
int num=;
for(int i=;i<=;++i)vec[i]=i;int zo=;
for(int i=;i>=;--i){
int y=x/jie[i];
x=x%jie[i];
num=num*+vec[y];
for(int j=y;j<zo;++j)vec[j]=vec[j+];zo--;
}
return num;
}
int main(){
for(int i=;i<=;++i)scanf("%d",&a[i]),x=x*+a[i];jie[]=;int mem=x;
for(int i=;i<=;++i)jie[i]=jie[i-]*i;
win=zx_hash();
q.push(node{zx_hash(x),});
while(!q.empty()){
int u=q.front().first,nn=q.front().second;q.pop();
if(u==win){
printf("%d\n",nn);
tag=;
break;
}
x=anti_hash(u);
for(int i=;i>=;--i)d1[r1[i]]=x%,d2[r2[i]]=x%,x/=;
int x1=,x2=;
for(int i=;i<=;++i)x1=x1*+d1[i],x2=x2*+d2[i];
x1=zx_hash(x1);x2=zx_hash(x2);
if(!ji[x1])ji[x1]=u,q.push(node{x1,nn+});
if(!ji[x2])ji[x2]=u,q.push(node{x2,nn+});
}
if(!tag){
printf("UNSOLVABLE");
return ;
}
x=mem;x=zx_hash(x);
while(win!=x){
ans[++tot]=win;win=ji[win];
}
ans[++tot]=x;
for(int i=tot;i>=;--i){
int qq=anti_hash(ans[i]);
for(int j=;j>=;--j)a[j]=qq%,qq/=;
printf("%d %d %d\n%d %d %d\n%d %d %d\n\n",a[],a[],a[],a[],a[],a[],a[],a[],a[]);
}
return ;
}
[ZJOI2005]九数码游戏(BFS+hash)的更多相关文章
- [ZJOI2005]九数码游戏
[ZJOI2005]九数码游戏 题目描述 输入输出格式 输入格式: 输入文件中包含三行三列九个数,同行的相邻两数用空格隔开,表示初始状态每个方格上的数字.初始状态不会是目标状态. 输出格式: 如果目标 ...
- 洛谷 P2578 [ZJOI2005]九数码游戏【bfs+康托展开】
只有9!=362880个状态,用康托展开hash一下直接bfs即可 #include<iostream> #include<cstdio> #include<cstrin ...
- LG2578 「ZJOI2005」九数码游戏 bfs
问题描述 LG2578 题解 用string+map去重. bfs即可. \(\mathrm{Code}\) #include<bits/stdc++.h> using namespace ...
- 洛谷 - P2578 - 九数码游戏 - bfs
https://www.luogu.org/problemnew/show/P2578 一个挺搞的东西,用康托展开做记忆化搜索可以少一个log的查询. #include <bits/stdc++ ...
- 万圣节后的早晨&&九数码游戏——双向广搜
https://www.luogu.org/problemnew/show/P1778 https://www.luogu.org/problemnew/show/P2578 双向广搜. 有固定起点终 ...
- HDU-1043 Eight八数码 搜索问题(bfs+hash 打表 IDA* 等)
题目链接 https://vjudge.net/problem/HDU-1043 经典的八数码问题,学过算法的老哥都会拿它练搜索 题意: 给出每行一组的数据,每组数据代表3*3的八数码表,要求程序复原 ...
- 【BZOJ】1054: [HAOI2008]移动玩具(bfs+hash)
http://www.lydsy.com/JudgeOnline/problem.php?id=1054 一开始我还以为要双向广搜....但是很水的数据,不需要了. 直接bfs+hash判重即可. # ...
- C#_界面程序_数码游戏
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- [BZOJ1054][HAOI2008]移动玩具 bfs+hash
1054: [HAOI2008]移动玩具 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2432 Solved: 1355[Submit][Stat ...
随机推荐
- [编程笔记]第一章 C语言概述
//C语言学习笔记 第一讲 C语言概述 第二讲 基本编程知识 第三讲 运算符和表达式 第四讲 流程控制 第五讲 函数 第六讲 数组 第七讲 指针 第八讲 变量的作用域和存储方式 第九讲 拓展类型 第十 ...
- react 路由4 学习
表单控件 受控表单组件 非受控的表单组件 demo:收集表单提交的数据 路由(V4) 特点:一切皆是组件 官网:https://reacttraining.com/react-router/ npm ...
- linux 安装ssh以及ssh用法与免密登录
想要免费登录就是把本地机器的id_rsa_pub的内容放到远程服务器的authorized_keys里面 一.配置yum和hosts文件 配置hosts文件: 命令:vi /etc/hosts 在文件 ...
- mybatis二级缓存详解
1 二级缓存简介 二级缓存是在多个SqlSession在同一个Mapper文件中共享的缓存,它是Mapper级别的,其作用域是Mapper文件中的namespace,默认是不开启的.看如下图: 1. ...
- 剑指offer(13)
题目: 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 思路: 判断当前两个根结点是否相等,如果相等,判断左右子树是否相等,如果不依次判断左右子树是否满足上 ...
- liunx安装nginx
参考 https://blog.csdn.net/dyllove98/article/details/41120789 1,去官网下载最新的包 官网地址:http://nginx.org/downlo ...
- django migrate报错(提前删除表等)
python3 manage.py makemigrations python3 manage.py migrate ##报错 改为##更改migrates的状态 python3 manage.py ...
- 微服务架构中APIGateway原理
背景 我们知道在微服务架构风格中,一个大应用被拆分成为了多个小的服务系统提供出来,这些小的系统他们可以自成体系,也就是说这些小系统可以拥有自己的数据库,框架甚至语言等,这些小系统通常以提供 Rest ...
- java_manual的一点体会
最近看了一下Alibaba的java_manual1.4,看了感觉有很多好的标准,这里摘录一些,也帮助自己的代码更加规范化 先放一些MySQL的规范: 这里附上MySQL官网给的参考手册上的 关键字和 ...
- qtp 自动化测试---点滴 获取属性性/修改窗体标题
1 GetROProperty获取对应属性值 value url (这里出错了) If Window("新增").WinObject("TRzDBEdit_10" ...