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样式变化
原因:苹果自带样式覆盖了 参考文章比较详细,就不自己写了,copy了一份~~~ @参考文章 只要在样式里面加一句去掉css去掉iPhone.iPad的默认按钮样式就可以了!~ input[type=& ...
- Servlet--ServletContext接口
Servlet--ServletContext接口 定义public interface ServletContext 定义了一个 Servlet 的环境对象,通过这个对象,Servlet 引擎向 S ...
- 02_HTML5+CSS详解第一天
视频来源:麦子学院 讲师:朱朝兵 HTML5概念:HTML即超文本标记语言(HyperText Makeup Language),是一种语法简单,结构清晰的解释型文档,不同于其他编程语言. HTML5 ...
- Shader 入门笔记(一)
本笔记,是根据自己学习shader的笔记,主要是参照冯乐乐的<Shader 入门精要> 和游戏蛮牛shaderLad视频 和网上一些博客. 为啥要学习这个呐? 自己其实之前学过一段时间的s ...
- 【转】AWK常用
awk是个优秀文本处理工具,可以说是一门程序设计语言.下面是awk内置变量. 一.内置变量表 属性 说明 $0 当前记录(作为单个变量) $1~$n 当前记录的第n个字段,字段间由FS分隔 FS 输入 ...
- JavaSE基础篇—MySQL基础知识点
MySQL MySQL是一种关系数据库管理系统,是一种开源软件.可搭配PHP和Apache可以有更好的性能,也可以工作在众多的平台上.Orcale是一个数据库创建多个用户,MySQL是一个用户创建多个 ...
- iometer测试工具
简介 Iometer 为计算机I/O子系统所作的工作就如同测力计为引擎所作的工作一样:它测定在可控制的负荷下系统的性能.Iometer 以前被称为"伽利略". Iometer 既是 ...
- mongodb监控常用方法
列举mongodb监控的常用命令 1.监控统计 mongostat 可用于查看当前QPS/内存使用/连接数,以及多个shard的压力分布 命令参考 ./mongostat --port 27071 - ...
- 程序员之殇 —— (Are you afraid of me? Don't be.)灵感=神秘感
Are you afraid of me? (你们怕我吗?) Don't be.(不用怕) I am a programmer who just won't die.(我是不会死的程序员) 自从跟踪到 ...
- JAVA关键字Volatile的特性
一.简述: 关键字Volatile是JAVA虚拟机提供的最轻量级的同步机制,但是它并不容易完全被正确.完整的理解,以致于许多程序员在遇到需要处理多线程数据竞争的时候一律使用synchronized来进 ...