[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 ...
随机推荐
- React Native之获取通讯录信息并实现类通讯录列表(ios android)
React Native之获取通讯录信息并实现类通讯录列表(ios android) 一,需求分析 1,获取通讯录信息,筛选出通讯录里有多少好友在使用某个应用. 2,获取通讯录信息,实现类通讯录,可拨 ...
- javascript中的 return false和return true
关于javascript中的 return false和return true,return 是javascript里函数返回值的关键字,一个函数内处理的结果可以使用return 返回,这样在调用函数 ...
- Mac上通过iterm 上传文件到服务器
.安装 brew install lrzsz #这里以homebrew方式安装12.脚本 拉取 https://github.com/mmastrac/iterm2-zmodem 两个sh文件,将他们 ...
- Tomcat启用GZIP压缩,提升web性能
一.前言 最近做了个项目,遇到这么一个问题:服务器返回给客户端的json数据量太大(大概65M),在客户端加载了1分多钟才渲染完毕,费时耗流量,用户体验极其不好.后来网上搜优化的方法,就是Http压缩 ...
- [转帖]tar高级教程:增量备份、定时备份、网络备份
tar高级教程:增量备份.定时备份.网络备份 作者: lesca 分类: Tutorials, Ubuntu 发布时间: 2012-03-01 11:42 ė浏览 27,065 次 61条评论 一.概 ...
- [转帖]CentOS 6 服务器安全配置指南(通用)
CentOS 6 服务器安全配置指南(通用) http://seanlook.com/2014/09/07/linux-security-general-settings/ 发表于 2014-09- ...
- ArcGIS 添加 MarkerSymbol 弹出“图形符号无法序列化为 JSON”错误
今天在做一个demo,向自定义图层中添加MarkerSymbol的时候,弹出“图形符号无法序列化为 JSON”错误,之前都没有出现过这个问题,我们首先来看一看我是怎样去添加图层,然后向图层中添加Gra ...
- Code::Blocks debug程序
设置Settings--->Compiler, 打上勾: Produce debugging symbols [-g] 需要在settings->debugger settings-> ...
- java 中的打印流
package cn.zhou; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.F ...
- XCTF 4th-WHCTF-2017 creakme
exe文件 运行一下 随便输一下 ps.这个曹操身边的故事挺有意思的 但是没啥卵用....... 查一下壳无壳 ida载入 发现找不到main函数 直接看start感觉逻辑乱乱的(萌新求不喷..... ...