HDU - 3567 IDA* + 曼哈顿距离 + 康托 [kuangbin带你飞]专题二
这题难度颇大啊,TLE一天了,测试数据组数太多了。双向广度优先搜索不能得到字典序最小的,一直WA。
思路:利用IDA*算法,当前状态到达目标状态的可能最小步数就是曼哈顿距离,用于搜索中的剪枝。下次搜索的限制不能直接加1,会超时,应该从当前状态到目标状态最小限制开始搜索。
AC代码
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<cmath> using namespace std; const int maxn = 4e5 + 5; int vis[maxn]; int st[9], goal[9]; const int dx[] = {1,0,0,-1}; const int dy[] = {0,-1,1,0}; const char dir[] = {'d','l','r','u'}; int fact[9], loc[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; } void get_pos() { for(int i = 0; i < 9; ++i) { loc[goal[i]] = i; } } int get_h(int *a) { //曼哈顿距离 int cnt = 0; for(int i = 0; i < 9; ++i) { if(a[i] == 0 || i == loc[a[i]]) continue; int x = i / 3, y = i % 3; int n = loc[a[i]]; int px = n / 3, py = n % 3; cnt += abs(x - px) + abs(y - py); } return cnt; } char ans[50]; int a[9]; // step + h <= maxd int maxd, nextd; int dfs(int step, int pos) { int h = get_h(a); // cut //printf("h = %d\n", h); if(h == 0) { printf("%d\n", step); ans[step] = '\0'; printf("%s", ans); return 1; } if(step + h > maxd) { nextd = min(nextd, step + h); return 0; } 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[pos], a[pz]); int code = KT(a); if(vis[code]) { swap(a[pos], a[pz]); continue; } vis[code] = 1; ans[step] = dir[i]; if(dfs(step + 1, pz)) return 1; vis[code] = 0; swap(a[pos], a[pz]); } return 0; } int main() { deal(); char str[50]; int T, kase = 1; scanf("%d", &T); while(T--) { int pos; scanf("%s", str); for(int i = 0; i < 9; ++i) { if(str[i] == 'X') { pos = i; st[i] = 0; } else st[i] = str[i] - '0'; } scanf("%s", str); for(int i = 0; i < 9; ++i) { if(str[i] == 'X') goal[i] = 0; else goal[i] = str[i] - '0'; } get_pos(); printf("Case %d: ", kase++); int code = KT(st); vis[code] = 1; for(maxd = get_h(st);;) { nextd = 1 << 30; memcpy(a, st, sizeof(a)); memset(vis, 0, sizeof(vis)); if(dfs(0, pos)) break; maxd = nextd; } printf("\n"); } return 0; }
如有不当之处欢迎指出!
HDU - 3567 IDA* + 曼哈顿距离 + 康托 [kuangbin带你飞]专题二的更多相关文章
- HDU - 1043 A* + 康托 [kuangbin带你飞]专题二
这题我第一次用的bfs + ELFhash,直接TLE,又换成bfs + 康托还是TLE,5000ms都过不了!!我一直调试,还是TLE,我才发觉应该是方法的问题. 今天早上起床怒学了一波A*算法,因 ...
- HDU - 3085 双向BFS + 技巧处理 [kuangbin带你飞]专题二
题意:有两只鬼,一个男孩女孩被困在迷宫中,男孩每秒可以走三步,女孩只能1步,鬼可以两步且可以通过墙.问男孩女孩是否可以在鬼抓住他们之前会合? 注意:每秒开始鬼先移动,然后两人开始移动. 思路:以男孩和 ...
- HDU - 3567 Eight II (bfs预处理 + 康托) [kuangbin带你飞]专题二
类似HDU1430,不过本题需要枚举X的九个位置,分别保存状态,因为要保证最少步数.要保证字典序最小的话,在扩展节点时,方向顺序为:down, left, right, up. 我用c++提交1500 ...
- 【算法系列学习三】[kuangbin带你飞]专题二 搜索进阶 之 A-Eight 反向bfs打表和康拓展开
[kuangbin带你飞]专题二 搜索进阶 之 A-Eight 这是一道经典的八数码问题.首先,简单介绍一下八数码问题: 八数码问题也称为九宫问题.在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的 ...
- HDU - 3533 bfs [kuangbin带你飞]专题二
看了好久的样例才看懂. 题意:有一个人要从(0,0)走到(n,m),图中有k个碉堡,每个碉堡可以向某个固定的方向每隔t秒放一次炮,炮弹不能穿越另一个碉堡,会被阻挡.人在移动的过程中不会被炮弹打到,也就 ...
- HDU - 3001 Travelling 状压dp + 三进制 [kuangbin带你飞]专题二
终于刷完搜索专题了. 题意:给定n个城市,每个城市参观不能超过两次,两个城市之间有道路通过需要花费X,求通过能所有城市的最小花费. 思路:每个城市有三个状态0,1,2,可用三进制存储所有城市的访问状态 ...
- HDU1560 DNA sequence IDA* + 强力剪枝 [kuangbin带你飞]专题二
题意:给定一些DNA序列,求一个最短序列能够包含所有序列. 思路:记录第i个序列已经被匹配的长度p[i],以及第i序列的原始长度len[i].则有两个剪枝: 剪枝1:直接取最长待匹配长度.1900ms ...
- 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)也是传送机,这 ...
随机推荐
- AMS的适用场景
AMS适用于网络音视频应用的各种场合,可以独立作为直播点播平台应用,也可以嵌入到用户的各种应用平台中,为客户提供音视频核心支撑,不同于其它提供云服务租给客户使用的产品,AMS是一套安装在企业内部服务器 ...
- 【Java SE】如何安装JDK以及配置Java运行环境
摘要:不管是作为苦逼的Java码农,还是高端大气的Java系统架构师,如果不会安装JDK以及配置Java运行环境,那就巧妇难为无米之炊,不能进行Java后续的代码编写.当然如果你是Myeclipse编 ...
- JDBC (二)
1 使用JDBC进行批处理 当需要向数据库发送一批SQL语句的时候,应该避免向数据库一条条的发送执行,而应该采用JDBC的批处理机制,以提高执行效率. 实现批处理的方式一: Statement.add ...
- convert图像格式批量转换
问题:利用GMT绘制生成了eps格式的图像,为了将图像插入到word中,且保持较高的分辨率,利用convert进行图像格式转换,将eps转换成tiff格式. code: $i ${name}.tif ...
- 前端通过Nginx反向代理解决跨域问题
在前面写的一篇文章SpringMVC 跨域,我们探讨了什么是跨域问题以及SpringMVC怎么解决跨域问题,解决方式主要有如下三种方式: JSONP CORS WebSocket 可是这几种方式都是基 ...
- Java - 双冒泡法排序
最开始的代码 我采用的是我原来进行快速排序所用的方法,一直做不出来. 为什么我会采用原来快速排序的方法?因为我的记忆中好像就是这样的,因此我根据记忆中的快速排序在进行改变,然而,却无法真正的写出双冒泡 ...
- 关于主机用户名显示为"-bash-4.1$"
牢记 <1> .(小数点)==> 代表一个任意字符 <2> *(星)====> 重复前面一个字符0到无穷次 1.出现这中情况是因为:用户环境变量的文件没了,通 ...
- JavaScript中的类继承
JavaScript是一个无class的面向对象语言,它使用原型继承而非类继承.这会让那些使用传统面向对象语言如C++和Java的程序员们感到困惑.正如我们所看到的,JavaScript的原型继承比类 ...
- Java 解压zip压缩包
因为最近项目需要批量上传文件,而这里的批量就是将文件压缩在了一个zip包里,然后读取文件进行解析文件里的内容. 因此需要先对上传的zip包进行解压.以下直接提供代码供参考: 1.第一个方法是用于解压z ...
- Effective Java 之-----返回零长度的数组或集合而不是null
如下代码,通常用户列表为空时,会习惯性返回null,因为这时会认为:null返回值比零长度数组更好,因为它避免了分配数组所需要的开销. private final List<UserBean&g ...