http://acm.hdu.edu.cn/showproblem.php?pid=1430

如果从start ---> end,每一次都bfs进行,那么就肯定会超时。

考虑到先把start映射到原始状态"12345678",然后又把end按照同样的规则,就是start的变化,映射到某一个地方。那么就可以看作是从固定的起点“12345678”-->newend,这个就可以打表了。

比如从87654321变化到12345678,那么就是8变成了1,7变成了2,6变成了3....。。那么end那里也按照这样变,在end中找一个8,变成1......以此类推。

相当于模仿start走动而已,肯定能走到的。

然后就可以打表。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset> class cantor { //求1...n的排列的第k大 && hash排列,
public : ///class默认是private,所以要加上public
int fac[];
cantor() { //预处理阶乘
fac[] = ;
for (int i = ; i <= ; ++i) {
fac[i] = fac[i - ] * i;
}
}
int decode(char str[], int lenstr) { //O(n * n)的hash
int ans = ;
for (int i = ; i < lenstr; ++i) {
int cnt = ;
for (int j = i + ; j <= lenstr; ++j) {
if (str[i] > str[j]) {
cnt++;
}
}
ans += cnt * fac[lenstr - i];
}
return ans + ;
}
vector<int> encode(int lenstr, int k) { //字典序排第k的是那个,k从1开始
vector<int>ans;
int toans;
bool vis[] = {};
for (int i = ; i <= lenstr; ++i) {
int t = k / fac[lenstr - i];
k %= fac[lenstr - i];
for (toans = ; toans <= lenstr; ++toans) {
if (vis[toans]) continue;
if (t == ) break;
t--;
}
ans.push_back(toans);
vis[toans] = true;
}
return ans;
}
} cantor;
char be[], en[];
void A(char str[]) {
for (int i = ; i <= ; ++i) {
swap(str[i], str[ - i]);
}
}
void B(char str[]) {
char t = str[];
for (int i = ; i >= ; --i) str[i] = str[i - ];
str[] = t;
t = str[];
for (int i = ; i < ; ++i) str[i] = str[i + ];
str[] = t;
}
void C(char str[]) {
char t1 = str[];
str[] = str[];
char t2 = str[];
str[] = t1;
t1 = str[];
str[] = t2;
str[] = t1;
}
struct node {
char str[];
string now;
node(char ss[]) {
strcpy(str + , ss + );
}
node() {}
} que[ + ];
bool vis[ + ];
string ans[ + ];
void bfs() {
char st[] = "q12345678";
int fr, tail;
fr = tail = ;
que[tail++] = node(st);
que[fr].now = "";
vis[cantor.decode(st, )] = true;
while (fr < tail) {
char t[];
strcpy(t + , que[fr].str + );
A(t);
int valt = cantor.decode(t, );
if (vis[valt] == false) {
vis[valt] = true;
strcpy(que[tail].str + , t + );
que[tail].now = que[fr].now + "A";
ans[valt] = que[tail].now;
tail++;
} strcpy(t + , que[fr].str + );
B(t);
valt = cantor.decode(t, );
if (vis[valt] == false) {
vis[valt] = true;
strcpy(que[tail].str + , t + );
que[tail].now = que[fr].now + "B";
ans[valt] = que[tail].now;
tail++;
} strcpy(t + , que[fr].str + );
C(t);
valt = cantor.decode(t, );
if (vis[valt] == false) {
vis[valt] = true;
strcpy(que[tail].str + , t + );
que[tail].now = que[fr].now + "C";
ans[valt] = que[tail].now;
tail++;
}
fr++;
}
}
int pos[], f[];
char ten[];
void work() {
for (int i = ; i <= ; ++i) {
pos[be[i] - ''] = i;
}
for (int i = ; i <= ; ++i) {
en[i] = pos[en[i] - ''] + '';
}
// cout << en + 1 << endl;
cout << ans[cantor.decode(en, )] << endl;
}
int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
// cout << cantor.decode("q87645321", 8) << endl;
bfs();
while (scanf("%s%s", be + , en + ) != EOF) work();
return ;
}

hdu 1430 魔板 康托展开 + 很好的映射的更多相关文章

  1. HDU 1430 魔板(康托展开+BFS+预处理)

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  2. hdu.1430.魔板(bfs + 康托展开)

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  3. HDU - 1430 魔板 【BFS + 康托展开 + 哈希】

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1430 思路 我刚开始 想到的 就是 康托展开 但是这个题目是 多组输入 即使用 康托展开 也是会T的 ...

  4. [HDU 1430] 魔板

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...

  5. HDU - 1430 魔板 (bfs预处理 + 康托)

    对于该题可以直接预处理初始状态[0, 1, 2, 3, 4, 5, 6, 7]所有可以到达的状态,保存到达的路径,直接打印答案即可. 关于此处的状态转换:假设有初始状态为2,3,4,5,0,6,7,1 ...

  6. hdu 1430 魔板 (BFS+预处理)

    Problem - 1430 跟八数码相似的一题搜索题.做法可以是双向BFS或者预处理从"12345678"开始可以到达的所有状态,然后等价转换过去直接回溯路径即可. 代码如下: ...

  7. hdu-1430 魔板 康拓展开+映射优化

    给定三种操作,将排列A转化为排列B,求最少步骤. 这种题目可以只跑一次bfs,比如只跑"12345678",那么如果遇到"23456781"->某个字符串 ...

  8. hdu 1430(BFS+康托展开+映射+输出路径)

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...

  9. hdu1430魔板(BFS+康托展开)

    做这题先看:http://blog.csdn.net/u010372095/article/details/9904497 Problem Description 在魔方风靡全球之后不久,Rubik先 ...

随机推荐

  1. Jquery改动页面标题title其他JS失效

    Jquery代码   $("title").html("hello"); 后来仅仅好用以下这段js代码来实现 Js代码   document.title=&qu ...

  2. Web安全漏洞及攻击

    背景介绍 先说一个在互联网上常见,但是普通人又不太理解的东西--“验证码”. 验证码(CAPTCHA)是“Completely Automated Public Turing test to tell ...

  3. 找中位数O(n)算法

    题目描写叙述: 给定一个未排序的整数数组,找到当中位数. 中位数是排序后数组的中间值,假设数组的个数是偶数个.则返回排序后数组的第N/2个数. 例子 给出数组[4, 5, 1, 2, 3], 返回 3 ...

  4. oracle--Windows不能在本地计算机启动OracleDBConsoleorcl .错误代码1

    安装完数据库后能够启动,重新启动电脑后,手动启动就会报错. 现象: Windows 不能在 本地计算机 启动 OracleDBConsoleorcl.有关很多其它信息.查阅系统事件日志.假设这是非 M ...

  5. Linux Shell 条件测试

    1. 文件测试 -d 目录 -s 文件非空 -f 是正规文件 -w 有写权限 -r 有读权限 -x 有执行权限 -L 符号连接 -u 文件有suid位设置

  6. eclipse中将web项目部署到tomcat

    eclipse中将web项目部署到tomcat. myeclipse部署WEB项目到tomcat比较方便,但eclipse貌似默认是不会替你将web自动部署到tomcat下的.你Run as该web项 ...

  7. Perl Compatible Regular Expressions

    http://www.pcre.org/ http://www.pcre.org/

  8. 可用内存free不足 hadoop3 无法启动 手动释放缓存 cache

    [root@hadoop3 hadoop]# xlfg total used free shared buff/cache availableMem: 15 0 2 0 12 14Swap: 7 0 ...

  9. js控制页面显示

    两个菜单切换显示页面内容: js控制代码, /** JS初始化 **/ $(document).ready(function() { $('#email_btn').click(function(){ ...

  10. 【ZJOI 2006】 物流运输

    [题目链接] 点击打开链接 [算法] 令cost(i,j) = 第i天到第j天走相同的路线,路线长度的最小值 那么,只需筛选出第i天到第j天可以装卸货物的码头,然后将这些码头之间连边,跑弗洛伊德(或其 ...