HDU - 3567 Eight II (bfs预处理 + 康托) [kuangbin带你飞]专题二
类似HDU1430,不过本题需要枚举X的九个位置,分别保存状态,因为要保证最少步数。要保证字典序最小的话,在扩展节点时,方向顺序为:down, left, right, up.
我用c++提交1500ms, G++提交858ms.
AC代码
#include<cstdio> #include<cstring> #include<queue> #include<string> #include<iostream> #include<algorithm> using namespace std; typedef int state[9]; const int maxn = 4e5 + 5; int vis[9][maxn]; const int dx[] = {1,0,0,-1}; const int dy[] = {0,-1,1,0}; const char dir[] = {'d','l','r','u'}; int fact[9]; void deal() { //1~8阶乘打表,方便编码 fact[0] = 1; for(int i = 1; i < 9; ++i) fact[i] = fact[i - 1] * i; } int KT(int *a) { int code = 0; for(int i = 0; i < 9; ++i) { int cnt = 0; for(int j = i + 1; j < 9; ++j) if(a[j] < a[i]) cnt++; code += fact[8 - i] * cnt; } return code; } int find_pos(int *a) { for(int i = 0; i < 9; ++i) { if(a[i] == 0) return i; } } struct node{ int a[9]; int code, step; int pos; node() { } node(int *b, int code, int step ,int pos):code(code), step(step), pos(pos) { memcpy(a, b, sizeof(a)); } }; struct Dirction { char dir; int step; int pre; Dirction() { } Dirction(char dir, int step, int pre):dir(dir), step(step), pre(pre){ } }d[9][maxn]; int st[9]; void bfs(int c) { queue<node>q; int code = KT(st); vis[c][code] = 1; d[c][code] = Dirction('x', 0, -1); int pp = find_pos(st); q.push(node(st, code, 0, pp)); while(!q.empty()) { node p = q.front(); q.pop(); state &a = p.a; int pos = p.pos; int x = pos / 3, y = pos % 3; for(int i = 0; i < 4; ++i) { int px = x + dx[i], py = y + dy[i]; if(px < 0 || py < 0 || px >= 3 || py >= 3) continue; int pz = px * 3 + py; swap(a[pz], a[pos]); code = KT(a); if(vis[c][code]) { swap(a[pz], a[pos]); continue; } vis[c][code] = 1; d[c][code] = Dirction(dir[i], p.step + 1, p.code); q.push(node(a, code, p.step + 1, pz)); swap(a[pz], a[pos]); } } } int op[][9] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 1, 0, 2, 3, 4, 5, 6, 7, 8, 1, 2, 0, 3, 4, 5, 6, 7, 8, 1, 2, 3, 0, 4, 5, 6, 7, 8, 1, 2, 3, 4, 0, 5, 6, 7, 8, 1, 2, 3, 4, 5, 0, 6, 7, 8, 1, 2, 3, 4, 5, 6, 0, 7, 8, 1, 2, 3, 4, 5, 6, 7, 0, 8, 1, 2, 3, 4, 5, 6, 7, 8, 0 }; void print(int code, int c) { if(d[c][code].pre == -1) return; print(d[c][code].pre, c); printf("%c", d[c][code].dir); } int main() { memset(vis, 0, sizeof(vis)); deal(); for(int i = 0; i < 9; ++i) { memcpy(st, op[i], sizeof(st)); bfs(i); } int a[9], b[9]; int T, kase = 1, ha[9]; char s[20]; scanf("%d", &T); while(T--) { int pos; scanf("%s", s); for(int i = 0; i < 9; ++i) { if(s[i] == 'X') { pos = i; a[i] = 0; } else a[i] = s[i] - '0'; } for(int i = 0; i < 9; ++i) { ha[a[i]] = op[pos][i]; } scanf("%s", s); for(int i = 0; i < 9; ++i) { if(s[i] == 'X') b[i] = 0; else b[i] = s[i] - '0'; a[i] = ha[b[i]]; } int code = KT(a); printf("Case %d: %d\n", kase++, d[pos][code].step); print(code, pos); printf("\n"); } return 0; }
如有不当之处欢迎指出!
HDU - 3567 Eight II (bfs预处理 + 康托) [kuangbin带你飞]专题二的更多相关文章
- HDU - 3567 IDA* + 曼哈顿距离 + 康托 [kuangbin带你飞]专题二
这题难度颇大啊,TLE一天了,测试数据组数太多了.双向广度优先搜索不能得到字典序最小的,一直WA. 思路:利用IDA*算法,当前状态到达目标状态的可能最小步数就是曼哈顿距离,用于搜索中的剪枝.下次搜索 ...
- HDU - 1043 A* + 康托 [kuangbin带你飞]专题二
这题我第一次用的bfs + ELFhash,直接TLE,又换成bfs + 康托还是TLE,5000ms都过不了!!我一直调试,还是TLE,我才发觉应该是方法的问题. 今天早上起床怒学了一波A*算法,因 ...
- HDU - 3085 双向BFS + 技巧处理 [kuangbin带你飞]专题二
题意:有两只鬼,一个男孩女孩被困在迷宫中,男孩每秒可以走三步,女孩只能1步,鬼可以两步且可以通过墙.问男孩女孩是否可以在鬼抓住他们之前会合? 注意:每秒开始鬼先移动,然后两人开始移动. 思路:以男孩和 ...
- 【算法系列学习三】[kuangbin带你飞]专题二 搜索进阶 之 A-Eight 反向bfs打表和康拓展开
[kuangbin带你飞]专题二 搜索进阶 之 A-Eight 这是一道经典的八数码问题.首先,简单介绍一下八数码问题: 八数码问题也称为九宫问题.在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的 ...
- HDU 3567 Eight II BFS预处理
题意:就是八数码问题,给你开始的串和结束的串,问你从开始到结束的最短且最小的变换序列是什么 分析:我们可以预处理打表,这里的这个题可以和HDU1430魔板那个题采取一样的做法 预处理打表,因为八数码问 ...
- HDU - 3533 bfs [kuangbin带你飞]专题二
看了好久的样例才看懂. 题意:有一个人要从(0,0)走到(n,m),图中有k个碉堡,每个碉堡可以向某个固定的方向每隔t秒放一次炮,炮弹不能穿越另一个碉堡,会被阻挡.人在移动的过程中不会被炮弹打到,也就 ...
- HDU - 1067 Gap (bfs + hash) [kuangbin带你飞]专题二
题意: 起初定28张卡牌的排列,把其中11, 21, 31, 41移动到第一列,然后就出现四个空白,每个空白可以用它的前面一个数的下一个数填充,例如43后面的空格可以用44填充,但是47后面即 ...
- HDU - 2102 A计划 (BFS) [kuangbin带你飞]专题二
思路:接BFS判断能否在限制时间内到达公主的位置,注意如果骑士进入传送机就会被立即传送到另一层,不会能再向四周移动了,例如第一层的位置(x, y, 1)是传送机,第二层(x, y, 2)也是传送机,这 ...
- 【算法系列学习】[kuangbin带你飞]专题二 搜索进阶 D - Escape (BFS)
Escape 参考:http://blog.csdn.net/libin56842/article/details/41909459 [题意]: 一个人从(0,0)跑到(n,m),只有k点能量,一秒消 ...
随机推荐
- 转-CSS padding margin border属性详解
原文链接:http://www.cnblogs.com/linjiqin/p/3556497.html 图解CSS padding.margin.border属性W3C组织建议把所有网页上的对像都放在 ...
- linkin大话设计模式--单例模式
linkin大话设计模式 开文前先弱弱的问一句:什么是设计模式?我在研究java2ee的时候有研究过,在学js的时候也有看到.设计模式的概念最早源于建筑设计大师<建筑的永恒算法>一书,它表 ...
- MySql按日期进行统计
1 数据库字段pk_time(Varchar) 当天的数据 SELECT * FROM 表 WHERE date(fk_time) = curdate(); 当月的数据 SELECT *FROM 表 ...
- Hibernate (三)
1 一对多的单向 示例:一个已经存在的学生,新建一个班级,然后将该学生加入到该班级之下 设置inverse="false" <?xml version="1.0&q ...
- php 通过curl获取远程数据,返回的是一个数组型的字符串,高手帮忙如何将这个数组类型的字符串变成数组。
如 Array([0] => Array([0] => Array([kd_status] => 已签收[kd_time] => 2014-04-30 18:59:43 [b] ...
- shell第四篇(上)
第四篇了解Shell 命令执行流程图 {网中人大哥推荐参考Learning the Bash Shell, 2nd Edition,第 178页:中文版229页} Shell 从标准输入或脚本中读取的 ...
- 重定向stdin stdout stderr |
在Linux下,当一个用户进程被创建的时候,系统会自动为该进程创建三个数据 流,也就是题目中所提到的这三个.那么什么是数据流呢(stream)? 我们知道,一个程序要运行,需要有输入.输出,如果出错, ...
- 【转】 SED多行模式空间
1. sed执行模板=sed '模式{命令1;命令2}' 即逐行读入模式空间,执行命令,最后输出打印出来 2. 为方便下面,先说下p和P,p打印当前模式空间内容,追加到默认输出之后,P打印当前模式空间 ...
- Func常用模块及API
Func常用模块及API Func提供了非常丰富的功能模块,包括: CommandModule(执行命令) CopyFileModule(拷贝文件) CpuModule(CPU信息) DiskModu ...
- H5WebSocket消息推送
1.效果图 2.前端代码 @{ ViewBag.Title = "Home Page"; } @*HTML5 WebSocket WebSocket是HTML5开始提供的一种在单个 ...