题意:八数码,但是转移的方式是转动,一共十二种,有多组询问,初态唯一,终态不唯一。

题解:初态唯一,那么可以预处理出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展开)的更多相关文章

  1. hdu-1043(八数码+bfs打表+康托展开)

    参考文章:https://www.cnblogs.com/Inkblots/p/4846948.html 康托展开:https://blog.csdn.net/wbin233/article/deta ...

  2. cdoj 414 八数码 (双向bfs+康拓展开,A*)

    一道关乎人生完整的问题. DBFS的优越:避免了结点膨胀太多. 假设一个状态结点可以扩展m个子结点,为了简单起见,假设每个结点的扩展都是相互独立的. 分析:起始状态结点数为1,每加深一层,结点数An ...

  3. CDOJ 490 UESTC 490 Swap Game(思路,逆序对)

    题意:有两种颜色的小球形成环,求最小交互次数使球相连. 题解:先解决另一个简单的问题,如果是一个链,把红球标记为1,蓝球标记为0,要排成升序需要多少次交换呢?答案是逆序对总数,原因是一次交互最多消除一 ...

  4. A*算法 -- 八数码问题和传教士过河问题的代码实现

    前段时间人工智能的课介绍到A*算法,于是便去了解了一下,然后试着用这个算法去解决经典的八数码问题,一开始写用了挺久时间的,后来试着把算法的框架抽离出来,编写成一个通用的算法模板,这样子如果以后需要用到 ...

  5. 八数码问题:C++广度搜索实现

    毕竟新手上路23333,有谬误还请指正. 课程设计遇到八数码问题(这也是一坨),也查过一些资料并不喜欢用类函数写感觉这样规模小些的问题没有必要,一开始用深度搜索却发现深搜会陷入无底洞,如果设定了深度限 ...

  6. ACM/ICPC 之 BFS-广搜进阶-八数码(经典)(POJ1077+HDU1043)

    八数码问题也称为九宫问题.(本想查查历史,结果发现居然没有词条= =,所谓的历史也就不了了之了) 在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同.棋盘上还有一个 ...

  7. BFS(八数码) POJ 1077 || HDOJ 1043 Eight

    题目传送门1 2 题意:从无序到有序移动的方案,即最后成1 2 3 4 5 6 7 8 0 分析:八数码经典问题.POJ是一次,HDOJ是多次.因为康托展开还不会,也写不了什么,HDOJ需要从最后的状 ...

  8. 双向广搜+hash+康托展开 codevs 1225 八数码难题

    codevs 1225 八数码难题  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond   题目描述 Description Yours和zero在研究A*启 ...

  9. UVALive 6665 Dragon’s Cruller --BFS,类八数码问题

    题意大概就是八数码问题,只不过把空格的移动方式改变了:空格能够向前或向后移动一格或三格(循环的). 分析:其实跟八数码问题差不多,用康托展开记录状态,bfs即可. 代码: #include <i ...

随机推荐

  1. maven工程导入eclipse后报错

    原因:需要重新部署下tomcat环境 解决方式: 右击->属性:

  2. OSP 与 Session

    大家都知道,OSP是不支持session的,换句话说,登录有效期是永久的.一般网站,如果你不操作一段时间以后,必须重新登录.osp不是这样的,你一旦登录后,即便服务器重启了,你依然能访问服务器并不需要 ...

  3. npm ERR! mathine_call@1.0.0 dev: `webpack-dev-server --inline --progress --config build/webpack.dev.conf.js` npm ERR! Exit status 1

    internal/modules/cjs/loader.js:583 throw err; ^ Error: Cannot find module 'webpack' at Function.Modu ...

  4. linux和windows下安装python拓展包及requirement.txt安装类库

    python拓展包安装 直接安装拓展包默认路径: Unix(Linux)默认路径:/usr/local/lib/pythonX.Y/site-packagesWindows默认路径:C:\Python ...

  5. DNS(域名系统)服务器

    DNS(Domain Name System),因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的Ip数串.通过主机名,最终得到该主机 ...

  6. 如何备份Chrome浏览器收藏夹

    前言:最近,由于工作需要,要卸载当前Chrome版本,并安装最新版Chrome.卸载前,意识到之前收藏在收藏夹里的很多知识链接还未备份,于是有了今天的话题:如何备份Chrome浏览器的收藏夹? 主题: ...

  7. Windwos10环境下的Geany的安装与新手使用

    相信学习Python的小伙伴都会接触到Geany这个轻量级的python文本编辑器吧,下面就是我对于安装Geany的一些小经验分享. 1:安装geany很简单,进入geany官网download下载相 ...

  8. UIActionSheet的最后一项点击失效

    在开发过程中,发现有时候UIActionSheet的最后一项点击失效,点最后一项的上半区域时有效,这是在特定情况下才会发生,这个场景就是试用了UITabBar的时候才有.解决办法: 在showView ...

  9. VxWorks实验六 基于优先级的抢占式调度及实验的源程序和实验步骤

    基于优先级的抢占式调度及实验的源程序和实验步骤 1 实验目的    1.学习并验证基于优先级的抢占式调度2 实验内容    在实验一建立的 project 中,创建3 个任务,对这三个任务使用基于优先 ...

  10. nutzboot 使用nacos替换zookeeper

    先放一段从网上拷贝一段分布式CAP理论的概念 分布式领域中存在CAP理论,且该理论已被证明:任何分布式系统只可同时满足两点,无法三者兼顾. ①C:Consistency,一致性,数据一致更新,所有数据 ...