POJ 1077 Eight & HDU 1043 Eight(康托展开+BFS)
来源:互联网 发布:java 角色权限 编辑:程序博客网 时间:2024/05/20 06:27
题目链接:1077 -- Eight Problem - 1043
两个题目几乎完全一致。不同的是,HDU的八数码这道题需要一次bfs,起点为123456789X,遍历完所有状态,同时用pre数组记录上一个状态,然后每次输入只需要一个while进行O(1)的查询。
方法没有什么特殊的,我用的是普通的bfs。这道题和其他的搜索题目不一样的一点是,9个格子,太大没有办法标记。这时可以利用康托展开。
康托展开是一个完美hash函数,可以将n个数的所有排列组合状态进行压缩。9个数进行全排列,记录状态需要大小1e10的数组,经过康托展开的映射后只需要大小为9!的数组。一个数组经过这个过程,可以得到这个数组在全排列的序号。比如213是组合{1, 2, 3}中的第2小的组合(下标从0开始)。那么该如何得到213的康托展开就由1*2!+0*1!+0*0!得到。第一位是2,当第一位的数小于2时,排列数一定小于213,比如123、132,所以有1*2!,再看小于第二位1的,小于2的数没有 所以有0*1!=0,所以小于213的{1,2,3}排列数有1*2!+0*1!=2个,所以213是第3个大的数。
POJ 1077
#include <set>#include <map>#include <cmath>#include <stack>#include <queue>#include <vector>#include <string>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;typedef long long LL;#define FIN freopen("in.txt", "r", stdin);#define FOUT freopen("out.txt", "w", stdout);const int INF = 0x3f3f3f3f;const int MAXN = 400005;char op[MAXN];int pre[MAXN], fac[55];bool vis[MAXN], flag;int CantorExpansion(LL m){ int str[10], pos = 8; while (m) { str[pos--] = m % 10; m /= 10; } int ret = 0; for (int i = 0; i < 8; i++) { int tmp = 0; for (int j = i + 1; j < 9; j++) if (str[i] > str[j]) tmp++; ret += tmp * fac[8 - i]; } return ret;}void bfs(LL start){ memset(vis, false, sizeof(vis)); memset(op, -1, sizeof(op)); queue<LL> q; int id; q.push(start); id = CantorExpansion(start); vis[id] = true; while (!q.empty()) { LL cur = q.front(); q.pop(); if (cur == 123456789) { stack<char> sta; id = CantorExpansion(cur); while (op[id] != -1) { sta.push(op[id]); id = pre[id]; } while (!sta.empty()) { printf("%c", sta.top()); sta.pop(); } puts(""); flag = true; return; } int str[10], pos = 8, nine; LL tcur = cur; while (tcur) { if (tcur % 10 == 9) nine = pos; str[pos--] = tcur % 10; tcur /= 10; } for (int i = 0; i < 4; i++) { if ((i == 0 && nine / 3 == 0) || (i == 1 && nine / 3 == 2) || (i == 2 && nine % 3 == 0) || (i == 3 && nine % 3 == 2)) continue; int tstr[10]; memcpy(tstr, str, 9 * sizeof(int)); if (i == 0) swap(tstr[nine], tstr[nine - 3]); else if (i == 1) swap(tstr[nine], tstr[nine + 3]); else if (i == 2) swap(tstr[nine], tstr[nine - 1]); else if (i == 3) swap(tstr[nine], tstr[nine + 1]); LL tt = 0; for (int i = 0; i < 9; i++) tt = tt * 10 + tstr[i]; int id = CantorExpansion(tt); if (!vis[id]) { if (i == 0) op[id] = 'u'; else if (i == 1) op[id] = 'd'; else if (i == 2) op[id] = 'l'; else if (i == 3) op[id] = 'r'; pre[id] = CantorExpansion(cur); vis[id] = true; q.push(tt); } } }}int main(){#ifndef ONLINE_JUDGE FIN;#endif // ONLINE_JUDGE //bfs(); fac[0] = fac[1] = 1; for (int i = 2; i < 9; i++) fac[i] = fac[i - 1] * i; char str[50]; while (gets(str)) { flag = false; int s = 0; for (int i = 0; str[i]; i++) { if (str[i] == 'x') s = s * 10 + 9; else if (str[i] != ' ') s = s * 10 + str[i] - '0'; } int id = CantorExpansion(s); if (id == 0) { printf("lr\n"); continue; } bfs(s); if (!flag) printf("unsolvable\n"); } return 0;}
HDU 1043
#include <set>#include <map>#include <cmath>#include <stack>#include <queue>#include <vector>#include <string>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;typedef long long LL;#define FIN freopen("in.txt", "r", stdin);#define FOUT freopen("out.txt", "w", stdout);const int INF = 0x3f3f3f3f;const int MAXN = 400005;char op[MAXN];int pre[MAXN], fac[55];bool vis[MAXN];int CantorExpansion(LL m){ int str[10], pos = 8; while (m) { str[pos--] = m % 10; m /= 10; } int ret = 0; for (int i = 0; i < 8; i++) { int tmp = 0; for (int j = i + 1; j < 9; j++) if (str[i] > str[j]) tmp++; ret += tmp * fac[8 - i]; } return ret;}void bfs(){ fac[0] = fac[1] = 1; for (int i = 2; i < 9; i++) fac[i] = fac[i - 1] * i; memset(vis, false, sizeof(vis)); memset(op, -1, sizeof(op)); queue<LL> q; int id; q.push(123456789); id = CantorExpansion(123456789); vis[id] = true; while (!q.empty()) { LL cur = q.front(); q.pop(); int str[10], pos = 8, nine; LL tcur = cur; while (tcur) { if (tcur % 10 == 9) nine = pos; str[pos--] = tcur % 10; tcur /= 10; } for (int i = 0; i < 4; i++) { if ((i == 0 && nine / 3 == 0) || (i == 1 && nine / 3 == 2) || (i == 2 && nine % 3 == 0) || (i == 3 && nine % 3 == 2)) continue; int tstr[10]; memcpy(tstr, str, 9 * sizeof(int)); if (i == 0) swap(tstr[nine], tstr[nine - 3]); else if (i == 1) swap(tstr[nine], tstr[nine + 3]); else if (i == 2) swap(tstr[nine], tstr[nine - 1]); else if (i == 3) swap(tstr[nine], tstr[nine + 1]); LL tt = 0; for (int i = 0; i < 9; i++) tt = tt * 10 + tstr[i]; int id = CantorExpansion(tt); if (!vis[id]) { if (i == 0) op[id] = 'd'; else if (i == 1) op[id] = 'u'; else if (i == 2) op[id] = 'r'; else if (i == 3) op[id] = 'l'; pre[id] = CantorExpansion(cur); vis[id] = true; q.push(tt); } } }}int main(){#ifndef ONLINE_JUDGE FIN;#endif // ONLINE_JUDGE bfs(); char str[50]; while (gets(str)) { int s = 0; for (int i = 0; str[i]; i++) { if (str[i] == 'x') s = s * 10 + 9; else if (str[i] != ' ') s = s * 10 + str[i] - '0'; } int id = CantorExpansion(s); if (id == 0) { printf("lr\n"); continue; } if (op[id] == -1) { printf("unsolvable\n"); continue; } while (id != 0) { printf("%c", op[id]); id = pre[id]; } puts(""); } return 0;}
0 0
- POJ 1077 Eight & HDU 1043 Eight(康托展开+BFS)
- [BFS+康托展开]Hdu 1043 Eight
- hdu 1043 /poj 1077 Eight(经典八数码问题,BFS+康托展开)
- hdu 1043/poj 1077 Eight (八数码 经典搜索题 bfs + 康托展开)
- POJ 1077 Eight (正向BFS + 康托展开)
- HDU 1043 Eight(bfs+康托展开)
- HDU 1043 Eight(康托展开)
- [POJ]1077 Eight 八数码:康托展开+BFS
- POJ 1077 Eight 八数码问题[康托展开 + BFS]
- hdu 3567 Eight II (bfs+康托展开+预处理)
- HDU Eight II(BFS+康托展开)
- hdu 1043 eight (搜索 + 康托展开)
- HDU 1043 Eight(反向BFS打表+康托展开)
- hdu 1043 Eight(bfs+康托)
- HDU 1043 Eight (BFS·八数码·康托展开)
- HDU ACM 1043 Eight->广度优先搜索(BFS)+康托展开(全排列hash)实践
- HDU 1043 Eight A*算法+康托展开
- HDU 1043 Eight(广搜+哈希+康托展开+打表)
- 剑指offer系列-T21包含min函数的栈
- Everything —— 文件搜索神器
- Linux下正则表达式
- android studio 导入项目出现 Error:Gradle version 2.2 is required.
- scrollview里面的页面元素往下掉automaticallyAdjustsScrollViewInsets
- POJ 1077 Eight & HDU 1043 Eight(康托展开+BFS)
- 219. Contains Duplicate II
- 分布式事务-简单总结
- 【DP】[NOI2011]NOI 嘉年华
- 基于 HTML5 的 WebGL 技术构建 3D 场景(一)
- "Android 性能优化"-Android面试必问"精华技能点"汇总
- Depends.exe —— PE依赖模块、导入导出函数查询
- 在阿里云 CentOS服务器上搭建nginx+mysql+php环境
- UESTC 2016 Summer Training #2 Div.2 A dp、递推、多阶段问题