CDOJ 485 UESTC 485 Game (八数码变形,映射,逆cantor展开)
题意:八数码,但是转移的方式是转动,一共十二种,有多组询问,初态唯一,终态不唯一。
题解:初态唯一,那么可以预处理出012345678的所有转移情况,然后将初态对012345678做一个映射,再枚举一下终态的所有情况,取最小值即可。
学了逆cantor展开,cantor展开是一个变进制数,每位上是原序列对应位置上的逆序值。那么求逆时候,就先除最大的位权得到对应位置上的逆序值,根据逆序值可以知道它在剩下的序列中第几大,然后标记它,迭代。状态转移有点麻烦。
#include<cstdio>
#include<cmath>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
typedef long long ll;
//#define local const int maxn = ;
int d[maxn];
int fac[] = { ,,,,,,,,};//,362880
int St[],Ed[]; int cantor(int *e) {
int ret = ;
for(int i = ; i < ; i++) {
int cnt = ;
for(int j = i+; j < ; j++)
if(e[j] < e[i]) cnt++;
ret += fac[-i] * cnt;
}
return ret;
} void invCantor(int *a,int code)
{
bool vis[] = {};
for(int i = ; i < ; i++){
int t = code/fac[-i];
int j;
for( j = ; j < ; j++){
if(!vis[j]){
if(t == ) break;
t--;
}
}
a[i] = j; vis[j] = ;
code %= fac[-i];
}
} int dir[][] = {
{,,,,,,,,},{,,,,,,,,},{,,,,,,,,},
{,,,,,,,,},{,,,,,,,,},{,,,,,,,,},
{,,,,,,,,},{,,,,,,,,},{,,,,,,,,},
{,,,,,,,,},{,,,,,,,,},{,,,,,,,,} };
queue<int> q; void BfsPre()
{
memset(d,-,sizeof(d) );
d[] = ;
q.push();
while(q.size()){
int u = q.front();q.pop();
int tmp[];
invCantor(tmp,u);
for(int i = ; i < ; i++){
int tmp2[];
for(int j = ; j < ; j++){
tmp2[j] = tmp[dir[i][j]];
}
int v = cantor(tmp2);
if(~d[v]) continue;
d[v] = d[u]+;
q.push(v);
}
}
} int query()
{
int mp[];
for(int i = ; i < ; i++) { mp[St[i]] = i; }
bool appear[] = {};
for(int i = ; i < ; i++){
if(~Ed[i]) appear[Ed[i] = mp[Ed[i]]] = ;
}
int vec[],sz = ;
for(int i = ; i < ; i++) {
if(!appear[i]) vec[sz++] = i;
}
if(sz == ) return ;
if(sz == ) return d[cantor(Ed)];
const int INF = 0x7fffffff;
int ans = INF;
int tmp[];
do{
int j = ;
for(int i = ; i < ; i++){
if(~Ed[i]) { tmp[i] = Ed[i]; }
else { tmp[i] = vec[j++]; }
}
int Hash = cantor(tmp);
if(~d[Hash]) ans = min(ans,d[Hash]);
}while(next_permutation(vec,vec+sz));
return ans!=INF? ans : -;
} int main()
{
#ifdef local
freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
#endif // local
int T;
BfsPre(); scanf("%d",&T);
for(int k = ; k <= T; k++){
printf("Case #%d: ",k);
for(int i = ; i < ; i ++){
scanf("%d",St+i);
St[i]--;
}
getchar();
char buf[];
for(int i = ; i < ; i++){
gets(buf);
for(int j = ; j < ; j+=){
if(''<=buf[j] && buf[j] <= ''){
Ed[i*+j/] = buf[j] - '';
}else Ed[i*+j/] = -;
}
}
int ans = query();
if(~ans) printf("%d\n",ans);
else printf("No Solution!\n");
} return ;
}
CDOJ 485 UESTC 485 Game (八数码变形,映射,逆cantor展开)的更多相关文章
- hdu-1043(八数码+bfs打表+康托展开)
参考文章:https://www.cnblogs.com/Inkblots/p/4846948.html 康托展开:https://blog.csdn.net/wbin233/article/deta ...
- cdoj 414 八数码 (双向bfs+康拓展开,A*)
一道关乎人生完整的问题. DBFS的优越:避免了结点膨胀太多. 假设一个状态结点可以扩展m个子结点,为了简单起见,假设每个结点的扩展都是相互独立的. 分析:起始状态结点数为1,每加深一层,结点数An ...
- CDOJ 490 UESTC 490 Swap Game(思路,逆序对)
题意:有两种颜色的小球形成环,求最小交互次数使球相连. 题解:先解决另一个简单的问题,如果是一个链,把红球标记为1,蓝球标记为0,要排成升序需要多少次交换呢?答案是逆序对总数,原因是一次交互最多消除一 ...
- A*算法 -- 八数码问题和传教士过河问题的代码实现
前段时间人工智能的课介绍到A*算法,于是便去了解了一下,然后试着用这个算法去解决经典的八数码问题,一开始写用了挺久时间的,后来试着把算法的框架抽离出来,编写成一个通用的算法模板,这样子如果以后需要用到 ...
- 八数码问题:C++广度搜索实现
毕竟新手上路23333,有谬误还请指正. 课程设计遇到八数码问题(这也是一坨),也查过一些资料并不喜欢用类函数写感觉这样规模小些的问题没有必要,一开始用深度搜索却发现深搜会陷入无底洞,如果设定了深度限 ...
- ACM/ICPC 之 BFS-广搜进阶-八数码(经典)(POJ1077+HDU1043)
八数码问题也称为九宫问题.(本想查查历史,结果发现居然没有词条= =,所谓的历史也就不了了之了) 在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同.棋盘上还有一个 ...
- BFS(八数码) POJ 1077 || HDOJ 1043 Eight
题目传送门1 2 题意:从无序到有序移动的方案,即最后成1 2 3 4 5 6 7 8 0 分析:八数码经典问题.POJ是一次,HDOJ是多次.因为康托展开还不会,也写不了什么,HDOJ需要从最后的状 ...
- 双向广搜+hash+康托展开 codevs 1225 八数码难题
codevs 1225 八数码难题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description Yours和zero在研究A*启 ...
- UVALive 6665 Dragonâs Cruller --BFS,类八数码问题
题意大概就是八数码问题,只不过把空格的移动方式改变了:空格能够向前或向后移动一格或三格(循环的). 分析:其实跟八数码问题差不多,用康托展开记录状态,bfs即可. 代码: #include <i ...
随机推荐
- Ajax的调试错误信息的输出
error: function(xhr, status, error) { console.log(xhr); console.log(status); console.log(error); }
- POJ - 2349 ZOJ - 1914 Arctic Network 贪心+Kru
Arctic Network The Department of National Defence (DND) wishes to connect several northern outposts ...
- 关于 == 和 equals() 的区别
对于正在学习java的,以及入行不久的小伙伴们,在面试中经常会被面试官问到 " == 和 equals() 的区别 ?"的问题,你是否回答好了呢? 示例一: //两个基本类型数据 ...
- Spring Security 表达式(Expressions) - hasRole示例
1.概述 Spring Security使用强大的Spring Expression Language(SpEL)提供各种各样的表达式.大多数这些Security表达式是针对上下文对象(当前经过身份验 ...
- PHP之递归函数
https://www.cnsecer.com/4146.html http://www.jb51.net/article/71424.htm //一列数字的规则如下:1,1,2,3,5,8,13,2 ...
- 洛谷P1313 计算系数
P1313 计算系数 题目描述 给定一个多项式(by+ax)^k,请求出多项式展开后x^n*y^m 项的系数. 输入输出格式 输入格式: 输入文件名为factor.in. 共一行,包含5 个整数,分别 ...
- JQuery Easyui/TopJUI 用JS创建数据表格并实现增删改查功能
JQuery Easyui/TopJUI 用JS创建数据表格并实现增删改查功能 html <table id="productDg"></table> &l ...
- 使用JS判断客户端、浏览器、操作系统类型
一.JS判断客户端类型 JS判断客户端是否是iOS或者Android手机移动端 通过判断浏览器的userAgent,用正则来判断手机是否是ios和Android客户端. 核心代码如下: 方法一: &l ...
- VxWorks实验八 信号
实验八信号1 实验目的1.学习使用信号2 实验内容在实验一建立的 project 中,编写一段信号处理程序,将其与SIGINT 相关连,使用kill()发送SIGINT 信号并调用信号处理程序.观察运 ...
- JavaScript进阶 - 第4章 跟着我的节奏走(流程控制语句)
第4章 跟着我的节奏走(流程控制语句) 4-1 做判断(if语句) if语句是基于条件成立才执行相应代码时使用的语句. 语法: if(条件) { 条件成立时执行代码} 注意:if小写,大写字母(IF) ...