HDU - 1430 魔板 【BFS + 康托展开 + 哈希】
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=1430
思路
我刚开始 想到的 就是 康托展开
但是这个题目是 多组输入 即使用 康托展开 也是会T的
正解应该是 预处理
然后我想到的预处理
因为每个状态 都是能够扩展出三种状态的
也就是说 每个状态都可以有三个儿子 这样 就像一棵树
我先把这棵树 建好 然后 询问的时候 再BFS搜索 这样就不用每次都康托展开了
但是还是T了
后来查了题解
发现 其实每次变换的都是位置,而上面的数字 是什么 其实不重要 我们可以给它哈希成 12345678
比如说 给出的 初始状态是 8 2 7 5 4 6 3 1 目标状态是 1 7 2 4 5 3 6 8
那么 我们可以理解为
8-1
2-2
7-3
5-4
4-5
6-6
3-7
1-8
那么 目标状态 通过哈希 就变为
8 3 2 5 4 7 6 1
问题就转化为
从 1 2 3 4 5 6 7 8 转移到 8 3 2 5 4 7 6 1 需要多少步骤
那么我们就可以 从 1 2 3 4 5 6 7 8 到达任意一种状态都预处理
这样 就可以直接输出路径了。。
我是这样处理的
保存父节点 递归输出
AC代码
#include <cstdio>
#include <cstring>
#include <ctype.h>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <stack>
#include <set>
#include <list>
#include <numeric>
#include <sstream>
#include <iomanip>
#include <limits>
#define CLR(a, b) memset(a, (b), sizeof(a))
#define pb push_back
#define bug puts("***bug***");
#define fi first
#define se second
#define stack_expand #pragma comment(linker, "/STACK:102400000,102400000")
#define syn_close ios::sync_with_stdio(false);cin.tie(0);
//#define bug
//#define gets gets_s
using namespace std;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <string, int> psi;
typedef pair <string, string> pss;
typedef pair <double, int> pdi;
const double PI = acos(-1.0);
const double E = exp(1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const int maxn = 4e4 + 1e3 + 10;
const int MOD = 142857;
const int FAC[] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880 };
int cantor(int b[8])
{
int ans = 0;
for (int i = 0; i < 8; i++)
{
int smaller = 0;
for (int j = i + 1; j < 8; j++)
{
if (b[i] > b[j])
smaller++;
}
ans += FAC[7 - i] * smaller;
}
return ans;
}
int arr[8];
pii pre[maxn];
int visit[maxn];
struct node
{
int arr[8];
int root;
};
void bfs()
{
for (int i = 0; i < maxn; i++)
visit[i] = 0;
int flag;
queue <node> q;
node u;
u.root = 0;
for (int i = 0; i < 8; i++)
u.arr[i] = i + 1;
q.push(u);
visit[0] = 1;
pre[0] = pii(-1, -1);
while (!q.empty())
{
node u = q.front(), vv;
q.pop();
// A
vv.arr[0] = u.arr[7];
vv.arr[1] = u.arr[6];
vv.arr[2] = u.arr[5];
vv.arr[3] = u.arr[4];
vv.arr[4] = u.arr[3];
vv.arr[5] = u.arr[2];
vv.arr[6] = u.arr[1];
vv.arr[7] = u.arr[0];
flag = cantor(vv.arr);
if (visit[flag] == 0)
{
visit[flag] = 1;
vv.root = flag;
pre[flag] = pii(u.root, 1);
q.push(vv);
}
// B
vv.arr[0] = u.arr[3];
vv.arr[1] = u.arr[0];
vv.arr[2] = u.arr[1];
vv.arr[3] = u.arr[2];
vv.arr[4] = u.arr[5];
vv.arr[5] = u.arr[6];
vv.arr[6] = u.arr[7];
vv.arr[7] = u.arr[4];
flag = cantor(vv.arr);
if (visit[flag] == 0)
{
visit[flag] = 1;
vv.root = flag;
pre[flag] = pii(u.root, 2);
q.push(vv);
}
// C
vv.arr[0] = u.arr[0];
vv.arr[1] = u.arr[6];
vv.arr[2] = u.arr[1];
vv.arr[3] = u.arr[3];
vv.arr[4] = u.arr[4];
vv.arr[5] = u.arr[2];
vv.arr[6] = u.arr[5];
vv.arr[7] = u.arr[7];
flag = cantor(vv.arr);
if (visit[flag] == 0)
{
visit[flag] = 1;
vv.root = flag;
pre[flag] = pii(u.root, 3);
q.push(vv);
}
}
}
int ed;
vector <int> ans;
void solve()
{
ans.clear();
while (pre[ed].fi != -1)
{
ans.pb(pre[ed].se);
ed = pre[ed].fi;
}
}
int main()
{
bfs();
string s1, s2;
while (cin >> s1 >> s2)
{
int arr[8];
map <char, int> mp;
for (int i = 0; i < 8; i++)
mp[s1[i]] = i + 1;
for (int i = 0; i < 8; i++)
arr[i] = mp[s2[i]];
ed = cantor(arr);
solve();
int len = ans.size();
for (int i = len - 1; i >= 0; i--)
printf("%c", 'A' + ans[i] - 1);
printf("\n");
}
}
HDU - 1430 魔板 【BFS + 康托展开 + 哈希】的更多相关文章
- 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 ...
- hdu1430魔板(BFS+康托展开)
做这题先看:http://blog.csdn.net/u010372095/article/details/9904497 Problem Description 在魔方风靡全球之后不久,Rubik先 ...
- 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——魔板,预处理,康托展开,置换,string类的+操作
Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可 ...
- [HDU 1430] 魔板
魔板 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...
- hdu 1430 魔板 康托展开 + 很好的映射
http://acm.hdu.edu.cn/showproblem.php?pid=1430 如果从start ---> end,每一次都bfs进行,那么就肯定会超时. 考虑到先把start映射 ...
- HDU_1043 Eight 【逆向BFS + 康托展开 】【A* + 康托展开 】
一.题目 http://acm.hdu.edu.cn/showproblem.php?pid=1043 二.两种方法 该题很明显,是一个八数码的问题,就是9宫格,里面有一个空格,外加1~8的数字,任意 ...
随机推荐
- 【LeetCode-面试算法经典-Java实现】【015-3 Sum(三个数的和)】
[015-3 Sum(三个数的和)] [LeetCode-面试算法经典-Java实现][全部题目文件夹索引] 原题 Given an array S of n integers, are there ...
- [译] 回调地狱——JavaScript异步编程指南
原文:Callback Hell 什么是 “回调地狱”? 在 JavaScript 中,我们经常通过回调来实现异步逻辑,一旦嵌套层级多了,代码结构就容易变得很不直观,最后看起来像这样: fs.read ...
- Devops成功的八大炫酷工具
原文链接:http://www.infoworld.com/article/3031009/devops/8-more-cool-tools-for-devops-success.html 为自动化和 ...
- SQL数据库从高版本到低版本的迁移,同时解决sql脚本文件太大无法打开的尴尬问题
as we known,sql数据库高版本向低版本还原是不太可能但是又经常会碰到的事,今天实测了一种方法 步骤:任务—>生成脚本—> 下一步->高级,选择数据库版本和编写脚本数据类型 ...
- 深入探析 Rational AppScan Standard Edition 新特性之 Glass Box 扫描
众所周知,Web 应用安全测试通常有黑盒安全测试和白盒安全测试两种方法.这两种方法孰优孰劣一直众议纷纷.广为公认的是,这两种测试方法有着良好地互补性,两种测试方法的结合是未来安全测试技术的发展趋势.G ...
- Storm/Cassandra集成错误:NoSuchMethodError: concurrent.Futures.withFallback
本文原文出处: http://blog.csdn.net/bluishglc/article/details/50443205 严禁不论什么形式的转载.否则将托付CSDN官方维护权益. 2015年的最 ...
- mfs客户端挂载
1.安装fuse yum install fuse fuse-devel 2.加载fuse模块 modprobe fuse 3.创建mfs用户 useradd mfs -s /sbin/nologin ...
- visual studio 2010 LNK1123解决方式
------------------------------------------------------------Lysen----------------------------------- ...
- mysql中去重复记录
Distinct 这个只能放在查询语句的最前面 参考 : https://www.cnblogs.com/lushilin/p/6187743.html
- hiho1080 更为复杂的买卖房屋姿势
题目链接: hihocoder1080 题解思路: 题目中对区间改动有两个操作: 0 区间全部点添加v 1 区间全部点改为v easy想到应该使用到两个懒惰标记 一个记录替换 一个记录增减 ...