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 ...
随机推荐
- GridView ,后台修改 跟新完毕,前端 未跟新处理
//Response.Redirect(Request.Url.ToString());//重新定位 GridView_dept.DataBind(); //重新绑定都可以
- 成为高手前必懂的TCP干货
目录 一.起源 二.TCP 协议 TCP 的特点? 怎么理解全双工? TCP 的数据包如何组织? 三.TCP 工作流程 四. 三次握手 五. 四次挥手 小结 我们在平时的开发过程中,或多或少都会涉猎到 ...
- pyhton 的i/o流和文件操作
Python 文件I/O 打印到屏幕 最简单的输出方法是用print语句,你可以给它传递零个或多个用逗号隔开的表达式.此函数把你传递的表达式转换成一个字符串表达式,并将结果写到标准输出如下: #!/u ...
- 剑指Offer的学习笔记(C#篇)-- 栈的压入、弹出序列
题目描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压 ...
- 不使用三方包时,如何在ThinkSNS中建立优雅的用户权限管理
什么是ThinkSNS ? ThinkSNS(简称TS),一款全平台综合性社交系统,为国内外大中小企业和创业者提供社会化软件研发及技术解决方案,目前最新版本为ThinkSNS+(简称TS+).Thin ...
- git clone 指定新建本地库位置
- nutzboot 使用nacos替换zookeeper
先放一段从网上拷贝一段分布式CAP理论的概念 分布式领域中存在CAP理论,且该理论已被证明:任何分布式系统只可同时满足两点,无法三者兼顾. ①C:Consistency,一致性,数据一致更新,所有数据 ...
- 架构sass文件
sass/ | |– base/ | |– _reset.scss # Reset/normalize | |– _typography.scss # Typography rules | ... # ...
- bzoj1822: [JSOI2010]Frozen Nova 冷冻波网络流
思路比较显然:二分答案,流流流 但是实现的时候感觉自己数学捉急.. 一开始算了个直线到点距离.... 应该是线段到点距离 #include <bits/stdc++.h> #define ...
- idea svn操作
https://blog.csdn.net/bug_love/article/details/72875511