Eight II HDU - 3567
Eight II
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 130000/65536 K (Java/Others)
Total Submission(s): 4621 Accepted Submission(s): 1006
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.
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.
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.
12X453786
12345678X
564178X23
7568X4123
dd
Case 2: 8
urrulldr
康拓展开 %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; // 康托展开值
}
#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的更多相关文章
- HDU 3567 Eight II(八数码 II)
HDU 3567 Eight II(八数码 II) /65536 K (Java/Others) Problem Description - 题目描述 Eight-puzzle, which is ...
- POJ-1077 HDU 1043 HDU 3567 Eight (BFS预处理+康拓展开)
思路: 这三个题是一个比一个令人纠结呀. POJ-1077 爆搜可以过,94ms,注意不能用map就是了. #include<iostream> #include<stack> ...
- HDU 3567 Eight II
Eight II Time Limit: 2000ms Memory Limit: 65536KB This problem will be judged on HDU. Original ID: 3 ...
- HDU 3567 Eight II 打表,康托展开,bfs,g++提交可过c++不可过 难度:3
http://acm.hdu.edu.cn/showproblem.php?pid=3567 相比Eight,似乎只是把目标状态由确定的改成不确定的,但是康托展开+曼哈顿为h值的A*和IDA*都不过, ...
- HDU 3567 Eight II BFS预处理
题意:就是八数码问题,给你开始的串和结束的串,问你从开始到结束的最短且最小的变换序列是什么 分析:我们可以预处理打表,这里的这个题可以和HDU1430魔板那个题采取一样的做法 预处理打表,因为八数码问 ...
- HDU - 3567 Eight II (bfs预处理 + 康托) [kuangbin带你飞]专题二
类似HDU1430,不过本题需要枚举X的九个位置,分别保存状态,因为要保证最少步数.要保证字典序最小的话,在扩展节点时,方向顺序为:down, left, right, up. 我用c++提交1500 ...
- hdu 1430+hdu 3567(预处理)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1430 思路:由于只是8种颜色,所以标号就无所谓了,对起始状态重新修改标号为 12345678,对目标状 ...
- (回文串 Manacher)吉哥系列故事——完美队形II -- hdu -- 4513
http://acm.hdu.edu.cn/showproblem.php?pid=4513 吉哥系列故事——完美队形II Time Limit: 3000/1000 MS (Java/Others) ...
- (全排列)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 ...
随机推荐
- vue中v-on支持的事件总结
资源事件 事件名称 何时触发 error 资源加载失败时. abort 正在加载资源已经被中止时. load 资源及其相关资源已完成加载. beforeunload window,document 及 ...
- [LC] 53. Maximum Subarray
Given an integer array nums, find the contiguous subarray (containing at least one number) which has ...
- Linux把内存挂载成硬盘提高读写速度
tmpfs是一种虚拟内存文件系统正如这个定义它最大的特点就是它的存储空间在VM里面,这里提一下VM(virtual memory),VM是由linux内核里面的vm子系统管理,现在大多数操作系统都采用 ...
- particlesJS is not defined
插件或者js文件在引入时需要注意引入顺序,每次都找很久的错误 一般引入min.js就可以,min.js意思就是压缩的js文件 引入时应该先加入min类的文件在引入配置文件 比如particles插件, ...
- Tarjan模板——求强连通分量
Tarjan求强连通分量的流程在这个博客讲的很清楚,再加上我也没理解透,这里就不写了. 缩点:将同一个连通块内的点视为同一个点. 扔一道模板题:codeVS2822爱在心中 第一问很显然就是求点数大于 ...
- Windows Server 2012 R2 强制卸载域控制器
本次实验要演示的是强制卸载域控制器并且在其他域控制器上删除不需要的服务器对象,这种情况在现实的生产使用环境中经常使用,每个企业每年都会有增减域控制器的时候,而且在减少了域控制器之后,原本的域还会继续使 ...
- [LC] 11. Container With Most Water
Given n non-negative integers a1, a2, ..., an , where each represents a point at coordinate (i, ai). ...
- SPSS|Data|Transfer|Analysis|Label|One sample test|Testval|Criables|
生物统计与实验设计-使用SPSS Data用于整合:Transfer用于预处理:Analysis用于数据的二维呈现:Label是在报表中呈现的名字: 给离散值编码: 对于离散值做数学计算: 均值比较用 ...
- python3下应用requests
模拟浏览器请求有两种,一种是不需要用户登录或者验证的请求,一种是需要用户登录或者验证的请求 那么我们先来说说不需要用户登录的方法 这种方式直接可以获取源码,用get的请求方式 登录的方式 获取这种页面 ...
- Typescript - 联合类型
原文:TypeScript基本知识点整理 零.序言 联合类型表示一个变量值可以是几种类型之一,我们可以使用 “|” 来分割每个类型: 联合类型的变量在被赋值时,会根据类型推断的规则推断出一个类型: 如 ...