HDU
来源:互联网 发布:js多选日期插件 编辑:程序博客网 时间:2024/06/02 05:05
典型的IDA*题目
估值函数:从当前状态移动到目标状态所需的最小步数(我们可以通过曼哈顿距离进行估值),用于剪枝
迭代:此处我们不再使深度每次加1,而是在搜索过程当中,记录大于len(len表示此次搜索的限制深度)的所有值中的最小值,作为下次迭代的限制深度
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <vector>#include <cmath>#include <stack>using namespace std;int factor[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880};int dx[] = {1, 0, 0, -1};int dy[] = {0, -1, 1, 0};int target, posx, posy, len, nextlen;bool vis[363000];int a[3][3], b[3][3], px[9], py[9];stack<int> s;int cantor(int t[][3]){ int x[9]; for (int i = 0; i < 9; i++) x[i] = t[i / 3][i % 3]; int ans = 0; for (int i = 0; i < 9; i++) { int cnt = 0; for (int j = i + 1; j < 9; j++) if (x[i] > x[j]) cnt++; ans += cnt * factor[9 - i - 1]; } return ans;}int geth(int t[][3]){ int ans = 0; for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) { if (!t[i][j]) continue; ans += abs(i - px[t[i][j]]) + abs(j - py[t[i][j]] % 3); } return ans;}bool ID_Astar(int state, int x, int y, int step){ if (state == target) return true; for (int i = 0; i <= 3; i++) { int cx = x + dx[i]; int cy = y + dy[i]; if (0 <= cx && cx <= 2 && 0 <= cy && cy <= 2) { swap(a[x][y], a[cx][cy]); int f = step + 1 + geth(a); if (f > len) nextlen = min(f, nextlen); if (f <= len) { int nextstate = cantor(a); if (!vis[nextstate]) { vis[nextstate] = true; s.push(i); if (ID_Astar(nextstate, cx, cy, step + 1)) return true; s.pop(); vis[nextstate] = false; } } swap(a[x][y], a[cx][cy]); } } return false;}int main(){ int T, k = 0; cin >> T; while (T--) { char ch; for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) { cin >> ch; if (ch == 'X') a[i][j] = 0, posx = i, posy = j; else a[i][j] = ch - '0'; } for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) { cin >> ch; if (ch == 'X') b[i][j] = 0; else { b[i][j] = ch - '0'; px[b[i][j]] = i; py[b[i][j]] = j; } } target = cantor(b); int start = cantor(a); cout << "Case " << ++k << ": "; memset(vis, 0, sizeof(vis)); vis[start] = true; len = 0; for (;;) { nextlen = 0x3f3f3f3f; while (!s.empty()) s.pop(); if (ID_Astar(start, posx, posy, 0)) break; if (nextlen == 0x3f3f3f3f) nextlen = len + 1; len = nextlen; } char cc[] = {'d', 'l', 'r', 'u'}; vector<int> ans; while (!s.empty()) ans.push_back(s.top()), s.pop(); cout << ans.size() << endl; for (int i = ans.size() - 1; i >= 0; i--) cout << cc[ans[i]]; cout << endl; } return 0;}
阅读全文
0 0
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- HDU
- 前端基础
- Shell脚本实现俄罗斯方块流程
- Android 支付宝调用测试版(沙箱环境)提示系统繁忙,请稍后再试(ALI40247)
- 常见PCB表面处理工艺简介
- USB 3G上网卡讲解之三
- HDU
- 排序算法的时间复杂度以及空间复杂度
- LeetCode-Median of Two Sorted Arrays
- HDU -2018 母牛的故事&&斐波那契兔子数列(函数递归)
- Ruby 中一些好用的方法(注意reduce方法)
- hdu1025 最长上升子序列 O(nlogn)优化版
- SpringBoot拦截全局异常并发送邮件给指定邮箱
- 秘传(加密)和签名的区别
- jQuery选择器要点