Eight II

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 130000/65536 K (Java/Others)
Total Submission(s): 4621    Accepted Submission(s): 1006

Problem Description
Eight-puzzle, which is also called "Nine grids", comes from an old game.

In this game, you are given a 3 by 3 board and 8 tiles. The tiles are numbered from 1 to 8 and each covers a grid. As you see, there is a blank grid which can be represented as an 'X'. Tiles in grids having a common edge with the blank grid can be moved into that blank grid. This operation leads to an exchange of 'X' with one tile.

We use the symbol 'r' to represent exchanging 'X' with the tile on its right side, and 'l' for the left side, 'u' for the one above it, 'd' for the one below it.

A state of the board can be represented by a string S using the rule showed below.

The problem is to operate an operation list of 'r', 'u', 'l', 'd' to turn the state of the board from state A to state B. You are required to find the result which meets the following constrains:
1. It is of minimum length among all possible solutions.
2. It is the lexicographically smallest one of all solutions of minimum length.

 
Input
The first line is T (T <= 200), which means the number of test cases of this problem.

The input of each test case consists of two lines with state A occupying the first line and state B on the second line.
It is guaranteed that there is an available solution from state A to B.

 
Output
For each test case two lines are expected.

The first line is in the format of "Case x: d", in which x is the case number counted from one, d is the minimum length of operation list you need to turn A to B.
S is the operation list meeting the constraints and it should be showed on the second line.

 
Sample Input
2
12X453786
12345678X
564178X23
7568X4123
 
Sample Output
Case 1: 2
dd
Case 2: 8
urrulldr
 
Author
zhymaoiing
 
Source
 
Recommend
zhouzeyong
题意:就是给起始八位码状态和结束八位码状态 求所需移动最少步数和操作步骤(以最小字典序)
 
这题卡了好久好久!!o(╥﹏╥)o ,看了大佬们的题解,才做出来的~
思路:这题结合康拓展开,映射,bfs打表就可以出来了
比如
起始状态12X453786  (120453786) 就可以替换为 120345678
 
映射关系
 
1 → 1
2 → 2
0 → 0
4 → 3
5 → 4
3 → 5
7 → 6
8 → 7
6 → 8
结束状态12345678X (12345678X) 就可以替换为 125348670
所以可以先将九种起始状态bfs打表
 
然后以结束状态八位码状态的康拓展开就可以得到我们想到的了~
 

康拓展开  %orz

康托展开是一个全排列到一个自然数双射,常用于构建哈希表时的空间压缩。 康托展开的实质是计算当前排列在所有由小到大全排列中的顺序,因此是可逆的。

以下称第x个全排列是都是指由小到大的顺序。

康拓展开式

      \[X=a_{n}\left ( n-1 \right )!+a_{n-1}\left ( n-2 \right )!+\cdots a_{1}\cdot 0!\]

例如,3 5 7 4 1 2 9 6 8 展开为 98884。因为X=2*8!+3*7!+4*6!+2*5!+0*4!+0*3!+2*2!+0*1!+0*0!=98884.

解释:

排列的第一位是3,比3小的数有两个,以这样的数开始的排列有8!个,因此第一项为2*8!

排列的第二位是5,比5小的数有1、2、3、4,由于3已经出现,因此共有3个比5小的数,这样的排列有7!个,因此第二项为3*7!

以此类推,直至0*0!

用途

显然,n位(0~n-1)全排列后,其康托展开唯一且最大约为n!,因此可以由更小的空间来储存这些排列。由公式可将X逆推出唯一的一个排列。

code  

static const int FAC[] = {, , , , , , , , , };   // 阶乘
int cantor(int *a, int n)
{
int x = ;
for (int i = ; i < n; ++i) {
int smaller = ; // 在当前位之后小于其的个数
for (int j = i + ; j < n; ++j) {
if (a[j] < a[i])
smaller++;
}
x += FAC[n - i - ] * smaller; // 康托展开累加
}
return x; // 康托展开值
}
 

 
 
accode 
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<string>
#include<vector>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<cmath>
#include<algorithm>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
#define MAX_N 362882 + 10
#define gcd(a,b) __gcd(a,b)
#define mem(a,x) memset(a,x,sizeof(a))
#define mid(a,b) a+b/2
#define stol(a) atoi(a.c_str())//string to long
int fac[];
int beg[][] ={{, , , , , , , , },{, , , , , , , , },{, , , , , , , , },{, , , , , , , , },{, , , , , , , , },{, , , , , , , , },{, , , , , , , , },{, , , , , , , , },{, , , , , , , , }};
int dir[][] = {{,},{,-},{,},{-,}};
char operate[] = "dlru";
int c;
int cal_cantor(int a[]){
int ans = ;
for (int i = ; i < ; i++){
int temp = ;
for (int j = i + ; j < ; j++){
if (a[j] < a[i]){
temp++;
}
}
ans += temp * fac[ - i];
}
return ans;
}
int temp[];
int mark[];
int start_cantor[];
struct Node{
int a[];
int x;
};
struct Vis{
int pre;
char p;
int step;
}vis[][MAX_N]; void bfs(int t,Node node){
queue<Node> que;
que.push(node);
while(que.size()){
Node n = que.front();
que.pop();
int n_contor = cal_cantor(n.a);
int pos = n.x;
for(int i = ; i < ; i++){
int x = n.x/;
int y = n.x%;
int nx = x + dir[i][];
int ny = y + dir[i][];
if(nx >= && nx < && ny >= && ny < ){
int cnt = nx * + ny;
swap(n.a[cnt],n.a[pos]);
n.x = cnt;
int v = cal_cantor(n.a);
if(vis[t][v].pre == -&&v!=start_cantor[t]){
vis[t][v].pre = n_contor;
vis[t][v].p = operate[i];
vis[t][v].step = vis[t][n_contor].step + ;
que.push(n);
}
n.x = pos;//
swap(n.a[cnt],n.a[pos]);
} } }
} void init(){
fac[] = fac[] = ;
for (int i = ; i < ; i++){
fac[i] = fac[i - ] * i;
}
for(int i = ; i < ; i++){
for(int j = ; j < MAX_N;j++)
vis[i][j].pre = -;
}
Node node;
for(int i = ; i < ; i++){
swap(node.a,beg[i]);
node.x = i;
start_cantor[i] = cal_cantor(node.a);
bfs(i,node);
swap(node.a,beg[i]);
}
}
int main(){
//std::ios::sync_with_stdio(false);
//std::cin.tie(0);
#ifndef ONLINE_JUDGE
freopen("D:\\in.txt","r",stdin);
freopen("D:\\out.txt","w",stdout);
#else
#endif
init();
int T;
scanf("%d",&T);
string str;
int t = ;
while(T--){
cin >> str;
for(int i = ; i < ; ++i){
temp[i] = (str[i] == 'X'? : str[i]-'');
if(str[i] == 'X')
c = i;
}
for(int i = ; i < ; ++i){
mark[temp[i]] = beg[c][i];
}
cin >> str;
for(int i = ; i < ; ++i){
temp[i] = (str[i] == 'X'? : str[i]-'');
temp[i] = mark[temp[i]];
}
Node n;
swap(n.a,temp);
int end_ = cal_cantor(n.a);
printf("Case %d: %d\n",++t,vis[c][end_].step);
string ans = "";
while(vis[c][end_].step!=){
ans = vis[c][end_].p + ans;
end_ = vis[c][end_].pre;
}
cout<<ans<<endl; } return ;
}
 

Eight II HDU - 3567的更多相关文章

  1. HDU 3567 Eight II(八数码 II)

    HDU 3567 Eight II(八数码 II) /65536 K (Java/Others)   Problem Description - 题目描述 Eight-puzzle, which is ...

  2. POJ-1077 HDU 1043 HDU 3567 Eight (BFS预处理+康拓展开)

    思路: 这三个题是一个比一个令人纠结呀. POJ-1077 爆搜可以过,94ms,注意不能用map就是了. #include<iostream> #include<stack> ...

  3. HDU 3567 Eight II

    Eight II Time Limit: 2000ms Memory Limit: 65536KB This problem will be judged on HDU. Original ID: 3 ...

  4. HDU 3567 Eight II 打表,康托展开,bfs,g++提交可过c++不可过 难度:3

    http://acm.hdu.edu.cn/showproblem.php?pid=3567 相比Eight,似乎只是把目标状态由确定的改成不确定的,但是康托展开+曼哈顿为h值的A*和IDA*都不过, ...

  5. HDU 3567 Eight II BFS预处理

    题意:就是八数码问题,给你开始的串和结束的串,问你从开始到结束的最短且最小的变换序列是什么 分析:我们可以预处理打表,这里的这个题可以和HDU1430魔板那个题采取一样的做法 预处理打表,因为八数码问 ...

  6. HDU - 3567 Eight II (bfs预处理 + 康托) [kuangbin带你飞]专题二

    类似HDU1430,不过本题需要枚举X的九个位置,分别保存状态,因为要保证最少步数.要保证字典序最小的话,在扩展节点时,方向顺序为:down, left, right, up. 我用c++提交1500 ...

  7. hdu 1430+hdu 3567(预处理)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1430 思路:由于只是8种颜色,所以标号就无所谓了,对起始状态重新修改标号为 12345678,对目标状 ...

  8. (回文串 Manacher)吉哥系列故事——完美队形II -- hdu -- 4513

    http://acm.hdu.edu.cn/showproblem.php?pid=4513 吉哥系列故事——完美队形II Time Limit: 3000/1000 MS (Java/Others) ...

  9. (全排列)Ignatius and the Princess II -- HDU -- 1027

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=1027 Ignatius and the Princess II Time Limit: 2000/100 ...

随机推荐

  1. python之time模块和hashlib模块

    一.time模块 import time print(time.strftime('%Y-%m-%d %H:%M:%S'))#获取当前的格式化时间,time.strftime(format) prin ...

  2. form中采用图片作为提交按钮

    <span style="font-size:14px;"><FORM name="formName" action="xxxx&q ...

  3. [LC] 232. Implement Queue using Stacks

    Implement the following operations of a queue using stacks. push(x) -- Push element x to the back of ...

  4. 蛋白质修饰|phosphors|mascot+X|

    生物医学大数据 重点:蛋白质定量 新蛋白可以是全新的蛋白质,也可以是知结构但未知功能的蛋白质,也可以是知道结构有新功能的蛋白质. 新蛋白鉴定可以使用以下方法. 基于基因组,可以基因组中的coding区 ...

  5. Trie图 模板

    trie图实际上是优化的一种AC自动机. trie图是在trie树上加一些失配指针,实际上是类似KMP的一种字符串匹配算法. 失配指针类似KMP的nx数组,有效地利用了之前失配的信息,优化了时间复杂度 ...

  6. Luogu_2434_[SDOI2005]区间

    题目描述 现给定n个闭区间[ai, bi],1<=i<=n.这些区间的并可以表示为一些不相交的闭区间的并.你的任务就是在这些表示方式中找出包含最少区间的方案.你的输出应该按照区间的升序排列 ...

  7. 初等数论-Base-1(筛法求素数,欧拉函数,欧几里得算法)

    前言 初等数论在OI中应用的基础部分,同机房的AuSquare和zhou2003君早就写完了,一直划水偷懒的Hk-pls表示很方,这才开始了这篇博客. \(P.S.\)可能会分部分发表. Base-1 ...

  8. 你相信吗:一加仑汽油可以给iPhone充电20年

    一直以来,苹果公司的iPhone系列手机受到了全世界人民的喜欢,很多人就此成为了果粉.或许是由于我们过于在意iPhone系列手机出彩的外形,所以忽略了很多关于iPhone手机有意思的消息,我们今天就来 ...

  9. Python实现简单Web服务器

    实验楼教程链接: https://www.shiyanlou.com/courses/552/labs/1867/document http原理详解(http下午茶): https://www.kan ...

  10. 修改从Maven中心仓库下载到本地的jar包的默认存储位置及远程仓库

    从Maven中心仓库下载到本地的jar包的默认存放在”${user.home}/.m2/repository”中,${user.home}表示当前登录系统的用户目录(如"C:\Users\g ...