hdu 1430 魔板 康托展开 + 很好的映射
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 魔板 康托展开 + 很好的映射的更多相关文章
- HDU 1430 魔板(康托展开+BFS+预处理)
魔板 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
- hdu.1430.魔板(bfs + 康托展开)
魔板 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
- HDU - 1430 魔板 【BFS + 康托展开 + 哈希】
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1430 思路 我刚开始 想到的 就是 康托展开 但是这个题目是 多组输入 即使用 康托展开 也是会T的 ...
- [HDU 1430] 魔板
魔板 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...
- HDU - 1430 魔板 (bfs预处理 + 康托)
对于该题可以直接预处理初始状态[0, 1, 2, 3, 4, 5, 6, 7]所有可以到达的状态,保存到达的路径,直接打印答案即可. 关于此处的状态转换:假设有初始状态为2,3,4,5,0,6,7,1 ...
- hdu 1430 魔板 (BFS+预处理)
Problem - 1430 跟八数码相似的一题搜索题.做法可以是双向BFS或者预处理从"12345678"开始可以到达的所有状态,然后等价转换过去直接回溯路径即可. 代码如下: ...
- hdu-1430 魔板 康拓展开+映射优化
给定三种操作,将排列A转化为排列B,求最少步骤. 这种题目可以只跑一次bfs,比如只跑"12345678",那么如果遇到"23456781"->某个字符串 ...
- hdu 1430(BFS+康托展开+映射+输出路径)
魔板 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...
- hdu1430魔板(BFS+康托展开)
做这题先看:http://blog.csdn.net/u010372095/article/details/9904497 Problem Description 在魔方风靡全球之后不久,Rubik先 ...
随机推荐
- Visual Studio VS如何拷贝一个项目的窗体文件到另一个项目
1 比如下我有一个项目,我要把这个Config整个窗体和代码拷贝到另一个项目 2 在新项目中添加现有项,然后把这个窗体相关的三个文件都添加到新的项目中 3 然后在新窗体中就什么都有了 ...
- DB 查询分析器 6.03 ,遨游于不论什么Windows操作系统之上的最棒的数据库client工具
DB 查询分析器 6.03 ,遨游于不论什么Windows操作系统之上的最棒的数据库client工具 中国本土程序猿马根峰(CSDN专訪马根峰:海量数据处理与分析大师的中国本土程序猿 .03版本 ...
- 【Mongodb教程 第一课 补加课1 】windows7 下安装mongodb 开启关闭服务
mongodb在2.2版本开始就不支持windows xp了(我想现在用xp的应该也是带着情怀的一部分人吧,我只是一个工匠而已),windows下server8 R2,64位,32位,只是32位只支持 ...
- 【扩展知识2】函数strlen()和非函数sizeof的使用
[扩展知识2]函数strlen()和非函数sizeof的使用 [扩展文件夹] strlen函数 sizeof ( 1 )函数strlen() 原型:size_tstrlen ( const char ...
- 使用变量作为js对象的属性名
<script> var test={aa:12,bb:34};//或者var test={}; var cc= "acqId" test[cc]=12; alert( ...
- 【bzoj2753】[SCOI2012]滑雪与时间胶囊
#include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> # ...
- ios app抓包分析
1 使用rvictl工具 这是mac下的一条命令.ios usb连mac,然后创建虚拟网络接口. 2 使用wireshark抓包 wireshark可以抓这个虚拟网络接口上的数据包.
- 前端富文本 js 版本
https://s3.pstatp.com/pgc/v2/resource/tt_ueditor_v3_temple/tt-editor.all.js?20180425
- HTML表单常用标签
名称 用例 备注 文本输入框 <input type="text" name="uname" value="" ...
- 建立自己的私有docker(ssl&login auth)
建立私有docker需要先建立ssl证书,然后建立htpass的登陆证书 最后使用nginx配置docker-compose.yml 参考: https://www.digitalocean.com/ ...