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先 ...
随机推荐
- Dropbox电面面经
他家电面有2轮,等待onsite.. . 电面1: 国人MM面的.这点感觉非常难得. 统计近期5分钟的点击量,实现hit和getHit两个函数.这题是他家高频题,我用deque实现的,hit的均摊时间 ...
- 架构设计经典案例:X窗体系统
X Window在1984年由MIT研发.它的设计哲学之中的一个是:提供机制.而非策略(类似面向对象思想中的"针对接口编程,而不是针对实现编程").机制(mechanism)是指须 ...
- Python 离线等价类
离线等价类的概念见离线等价类 最近在清洗数据的时候涉及到要将相似度比较高的文件夹合并,特征比对得到是1:1的对,比如: (a,b),(c,d),(a,c)...,那么合并的时候就涉及到将这些等价的对合 ...
- [转] When to use what language and why
Published by Seraphimsan Oct 13, 2010 (last update: Oct 14, 2010) When to use what language and why ...
- js调试记录,将客户的调试信息保存到服务器端的一个小方法。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Visual Studio Code 常用插件
这里记录在Visual Studio Code中,我经常用到的插件. C#这个就不必说了,想用VIsual Studio Code调试和编辑C#代码,必须要装这个插件.东西还好,就是每次安装和更新插件 ...
- 阿里云Ubuntu部署java web(1) - 系统配置
系统版本号:ubuntu 12.04 64位 ssh链接服务器(使用终端远程链接): ssh -l username IP地址 假设出现相似例如以下错误: @ WARNING: REMOTE H ...
- BZOJ_5369_[Pkusc2018]最大前缀和_状压DP
BZOJ_5369_[Pkusc2018]最大前缀和_状压DP Description 小C是一个算法竞赛爱好者,有一天小C遇到了一个非常难的问题:求一个序列的最大子段和. 但是小C并不会做这个题,于 ...
- AutoIT: 如何通过坐标相对位置来对无法识别的Menu以及GridView进行定位点击操作
一般情况下,GridView中的数据来自数据库,我们通过Windows Info,是无法获取GridView中的信息的.而软件定制的Menu,很多时候无法通过系统提供的WinMenuSelectIte ...
- appium学习【四】:第一个appium脚本
#coding=utf-8 import os import HTMLTestRunner import unittest import time import sys from appium imp ...