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. LeetCode 67 Add Binary(二进制相加)(*)

    翻译 给定两个二进制字符串,返回它们的和(也是二进制字符串). 比如, a = "11" b = "1" 返回 "100". 原文 Give ...

  2. dva/dynamic

    1.安装: yarn add dva 2.引入: import dynamic from 'dva/dynamic'; * dva路由跳转 * dynamic(app, model, componen ...

  3. Dubbo应用启动与停止脚本,超具体解析

    本周刚好研究了一下dubbo的启动脚本,所以在官网的启动脚本和公司内部的启动脚本做了一个整理,弄了一份比較通过的Dubbo应用启动和停止脚本.          以下的脚本仅仅应用于配置分离的应用.什 ...

  4. iOS开发--常用技巧 (MJRefresh详解)

         iOS开发--常用技巧 (MJRefresh详解) https://github.com/CoderMJLee/MJRefresh 下拉刷新01-默认 self.tableView.head ...

  5. C++问题记录

    问题idx: 1) 怎么在VS2010下新建一个像VC6.0 中那样的控制台C++程序. cdate: 2014-4-24 A1: VC6.0 对标准C++集的支持不是太好, VS2010也有一些吧, ...

  6. vsCode 常用快捷键(mac 版)

    光标多行显示: commond+Alt+topArrow/downArrow 查找:commond+F 查找并按顺序切换下一个:commond+G 跳转到某一行: ctrl+G 输入行号跳转 跳转到某 ...

  7. 基于FFMPEG SDK流媒体开发1---解码媒体文件流信息

    近期项目涉及到流媒体等开发,因为有过开发经验深知其难度所在,没办法仅仅能又一次拾起,最新版的SDK被改的一塌糊涂,只是大体的开发思路都是一样的,看多少书查多少资料都无用,一步一步的编写代码 才是学好的 ...

  8. go内存泄露case

    用go写了一个守护进程程序:用于检測redis的存活状态并将结果写到zookeeper中,部署到redis机器上.对于每一个redis实例会有一个goroutine每隔固定时间去检測其状态,由主gor ...

  9. 2016/2/26 jQuery的技术 1,安装 2,语法选择器$ 事件触发 3,常用jQuery函数

    在<网页制作Dreamweaver(悬浮动态分层导航)>中,运用到了jQuery的技术,轻松实现了菜单的下拉.显示.隐藏的效果,不必再用样式表一点点地修改,省去了很多麻烦,那么jQuery ...

  10. 表单提交数据量大于2m,java 后台接受不到表单传递过来的数据

    一般来说 post请求提交的数据无大小限制,但是tomcat 设置默认的表单传输数据大小不能2m,这时候当数据大于2m后台接收达不到表单的数据,需要修改tomcat的server.xml的的maxPo ...