HDU_1430 魔板 【BFS+康托展开+置换】
一、题面
二、分析
该题与之前做的八数码不同,它是一个2*4的棋盘,并且没有空的区域。这样考虑的情况是很少的,依然结合康托展开,这时康托展开最多也只乘7的阶乘,完全可以BFS先预处理一遍。
这里需要注意,在处理的时候,仔细读题,他的二维变一维的顺序是顺时针一遍读过来的。
预处理完后,这里需要用一个小技巧,就是置换。
$$ \begin{pmatrix} 3 & 2 & 1 & 4 & 5 & 6 & 7 & 8\\1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 \\ \end{pmatrix} $$
上面使用的例子是$32145678$,然后相当于把它移到了和$12345678$一个起跑线上,这样做的好处就是我们预处理的答案能够适用所有情况。
假设目标状态是$87654321$,这样把目标状态置换成与上面对应的即可。
$$ \begin{pmatrix} 8 & 7 & 6 & 5 & 4 & 3 & 2 & 1\\8 & 7 & 6 & 5 & 4 & 1 & 2 & 3 \\ \end{pmatrix} $$
这样就可以直接输出结果了。
三、AC代码
#include <cstdio>
#include <iostream>
#include <fstream>
#include <cstring>
#include <queue>
#include <algorithm> using namespace std; const int MAXN = ;
const int fac[] = {, , , , , , , , , }; //factorial
bool visit[MAXN];
struct Node
{
int m[];
int cat;
};
char op[] = "ABC";
string ans[MAXN]; void A(Node &t)
{
std::reverse(t.m , t.m+);
} void B(Node &t)
{
int temp = t.m[];
for(int i = ; i > ; i--)
{
t.m[i] = t.m[i-];
}
t.m[] = temp;
temp = t.m[];
for(int i = ; i < ; i++)
{
t.m[i] = t.m[i+];
}
t.m[] = temp;
} void C(Node &t)
{
int temp = t.m[];
t.m[] = t.m[];
t.m[] = t.m[];
t.m[] = t.m[];
t.m[] = temp;
} int Cantor(int s[])
{
int t, ans = ;
for(int i = ; i < ; i++)
{
t = ;
for(int j = i+; j < ; j++)
{
if(s[j] < s[i])
t++;
}
ans += t*fac[-i];
}
return ans;
} void bfs()
{
memset(visit, , sizeof(visit));
Node t;
for(int i = ; i < ; i++)
t.m[i] = i+;
t.cat = Cantor(t.m);
queue<Node> Q;
ans[t.cat] = "";
visit[t.cat] = ;
Q.push(t);
while(!Q.empty())
{
Node p = Q.front();
Q.pop();
for(int i = ; i < ; i++)
{
t = p;
switch(i)
{
case : A(t);break;
case : B(t);break;
case : C(t);break;
}
t.cat = Cantor(t.m);
if( !visit[t.cat] )
{ ans[t.cat] = ans[p.cat]+op[i];
visit[t.cat] = ;
Q.push(t);
}
}
} } int main()
{
//freopen("input.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
char s[];
int a[] = {}, b[] = {};
bfs();
while(scanf("%s", s)!=EOF)
{
for(int i = ; i < ; i++)
{
a[s[i] - ''] = i+;
}
scanf("%s", s);
for(int i = ; i < ; i++)
{
b[i] = a[s[i] - ''];
}
cout << ans[Cantor(b)] << endl;
}
return ;
}
HDU_1430 魔板 【BFS+康托展开+置换】的更多相关文章
- HDU_1430——魔板,预处理,康托展开,置换,string类的+操作
Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可 ...
- hdu.1430.魔板(bfs + 康托展开)
魔板 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
- hdu1430魔板(BFS+康托展开)
做这题先看:http://blog.csdn.net/u010372095/article/details/9904497 Problem Description 在魔方风靡全球之后不久,Rubik先 ...
- HDU 1430 魔板(康托展开+BFS+预处理)
魔板 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
- HDU_1043 Eight 【逆向BFS + 康托展开 】【A* + 康托展开 】
一.题目 http://acm.hdu.edu.cn/showproblem.php?pid=1043 二.两种方法 该题很明显,是一个八数码的问题,就是9宫格,里面有一个空格,外加1~8的数字,任意 ...
- 魔板 (bfs+康托展开)
# 10027. 「一本通 1.4 例 2」魔板 [题目描述] Rubik 先生在发明了风靡全球魔方之后,又发明了它的二维版本--魔板.这是一张有 888 个大小相同的格子的魔板: 1 2 3 4 8 ...
- HDU - 1430 魔板 【BFS + 康托展开 + 哈希】
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1430 思路 我刚开始 想到的 就是 康托展开 但是这个题目是 多组输入 即使用 康托展开 也是会T的 ...
- HDU1430;魔板(BFS+康托展开)
传送门 题意 给出初始序列与终止序列,给出三种操作,问最少经过几次操作能使初始->终止,输出操作(字典序最小) 分析 字符串只有8个字符,使用康托展开. 1.BFS将所有序列从"123 ...
- hdu1430 魔板(康拓展开 bfs预处理)
魔板 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...
随机推荐
- opennebula模板对照比较
良好模板 有问题模板
- MCMC 破译密码 http://mlwhiz.com/blog/2015/08/21/MCMC_Algorithms_Cryptography/
# AIM: To Decrypt a text using MCMC approach. i.e. find decryption key which we will call cipher fro ...
- Yii2中ACF和RBAC
ACF ( Access Control Filter) ACF ( Access Control Filter)官网的解释就是一个可以在模型或控制器执行行为过滤器,当有用户请求时,ACF将检查acc ...
- SQLServer跨库查询--分布式查询
出处:http://www.cnblogs.com/doosmile/archive/2012/03/16/2400646.html --用openrowset连接远程SQL或插入数据 --如果只是临 ...
- python核心编程第3章课后题答案(第二版55页)
3-4Statements Ues ; 3-5Statements Use\(unless part of a comma-separated sequence in which case \ is ...
- 编写高质量代码改善C#程序的157个建议——建议21:选择正确的集合
建议21:选择正确的集合 要选择正确的集合,首先要了解一些数据结构的知识.所谓数据结构,就是相互之间存在一种或多种特定关系的数据元素的集合. 集合的分类参考下图: 由于非泛型集合存在效率低及非类型安全 ...
- <%@ include > 与< jsp:include >
include指令表示在JSP编译时插入一个包含文本或者代码的文件,把文件中的文本静态地包含过去.也就是说,会把被包含的页面拷贝到包含的页面中指令所在的位置. 语法格式:<%@ include ...
- Android Hander、Looper、Message三者之间的联系
1.首先Looper.prepare()在本线程中保存一个Looper实例,然后该实例中保存一个MessageQueue对象:因为Looper.prepare()在一个线程中只能调用一次,所以Mess ...
- [.net 多线程]ThreadPool的安全机制
ThreadPool类,有两个方法我们没有用到,UnsafeQueueUserWorkItem 和UnsafeRegisterWaitForSingleObject. 为了完全理解这些方法,首先,我们 ...
- 正确处理类的复合关系------新标准c++程序设计
假设要编写一个小区养狗管理程序,该程序需要一个“主人”类,还需要一个“狗”类.狗是有主人的,主人也有狗.假定狗只有一个主人,但一个主人可以有最多10条狗.该如何处理“主人”类和“狗”类的关系呢?下面是 ...