HDU 1043 搜索 A*算法
2016-03-22 19:40
441 查看
#include <iostream> #include <cstdio> #include <queue> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; const int maxn = 4E5 + 10; const int mlen = 30; char str[mlen], D[] = "udlr"; int ha[9] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320}; int dir[4][2] = {{ -1, 0}, {1, 0}, {0, -1}, {0, 1}}; int vis[maxn], n; struct Node { int f[3][3], x, y, g, h, hash_num; bool operator < (const Node &other) const { return h + g > other.h + other.g; } void print() { cout << x << ' ' << y << ' ' << g << ' ' << h << ' ' << hash_num << endl; for (int i = 0; i < 9; i++) cout << f[i / 3][i % 3] << ' '; cout << endl; } }; struct Path { int pre; char ch; }; Path p[maxn]; int Get_Hash(const Node &E) { int res[9], ans = 0; for (int i = 0; i < 9; i++) res[i] = E.f[i / 3][i % 3]; for (int i = 0; i < 9; i++) { int k = 0; for (int j = 0; j < i; j++) if (res[j] > res[i]) k++; ans += ha[i] * k; } return ans; } int Get_H(const Node &E) { int ans = 0; for (int i = 0; i < 9; i++) if (E.f[i / 3][i % 3]) ans += abs(i / 3 - (E.f[i / 3][i % 3] - 1) / 3) + abs(i % 3 - (E.f[i / 3][i % 3] - 1) % 3); return ans; } bool Get_Dir(const Node &E, int i, int &X, int &Y) { X = E.x + dir[i][0], Y = E.y + dir[i][1]; if (X < 0 || X >= 3 || Y < 0 || Y >= 3) return 0; else return 1; } void print(int x) { if (p[x].pre == -1) return; else print(p[x].pre); printf("%c", p[x].ch); } void A_Star(Node E) { Node A, B; int X, Y, K; memset(vis, 0, sizeof(vis)); for (int i = 0; i < 9; i++) A.f[i / 3][i % 3] = (i + 1) % 9; int end_ans = Get_Hash(A); E.hash_num = Get_Hash(E); E.g = 0, E.h = Get_H(E); vis[E.hash_num] = 1; p[E.hash_num].pre = -1; if (E.hash_num == end_ans) {printf("\n"); return;} priority_queue<Node>que; que.push(E); while (!que.empty()) { B = que.top(); que.pop(); for (int i = 0; i < 4; i++) if (Get_Dir(B, i, X, Y)) { A = B; swap(A.f[B.x][B.y], A.f[X][Y]); K = Get_Hash(A); if (vis[K]) continue; else vis[K] = 1; A.hash_num = K, A.x = X, A.y = Y, A.g++, A.h = Get_H(A); p[K].pre = B.hash_num, p[K].ch = D[i]; if (K == end_ans) {print(K); printf("\n"); return;} que.push(A); } } } int main(int argc, char const *argv[]) { while (gets(str)) { n = strlen(str); Node E; for (int i = 0, cnt = 0; i < n; i++) { if (str[i] == ' ') continue; if (str[i] != 'x') E.f[cnt / 3][cnt % 3] = str[i] - '0'; else { E.f[cnt / 3][cnt % 3] = 0; E.x = cnt / 3; E.y = cnt % 3; } cnt++; } int tol = 0; for (int i = 0; i < 9; i++) if (E.f[i / 3][i % 3] == 0) continue; else for (int j = 0; j < i; j++) if (E.f[j / 3][j % 3] == 0) continue; else if (E.f[j / 3][j % 3] > E.f[i / 3][i % 3]) tol++; if (tol & 1) printf("unsolvable\n"); else A_Star(E); } return 0; }
给出一个3*3的矩阵里面是12345678x的排列,每次可以移动x到四个方向,求一条路径把它变成12345678x。
其实就是以前的手机上带的那个智能拼图,有一块是空的,通过上下左右移动空的最后让所有位置复原。
康拓展开,保存状态以供哈希。对曼哈顿距离进行A*搜索。
相关文章推荐
- 51nod 1276:岛屿的数量 (贪心)
- 安卓自定义view之打造滚动的通知栏
- html 最简遮罩层
- MyBatis教程
- pycaffe 中遇到的一些不能运行的问题的解决办法
- 一元函数对象的函数重载
- 背景图片与背景颜色的问题
- PHP调用内容DES加密的SOAP接口
- 作业三 代码规范 代码复审 PSP
- poj-3094-quicksum
- 1.2.2 Text_Reverse
- 第四周上机实践项目 项目1--求最大公约数
- 图像的稀疏表示——ScSPM和LLC的总结
- BZOJ 1195: [HNOI2006]最短母串
- android中的xml的tools
- Android输入法弹出时覆盖输入框问题
- HDU 2107 Founding of HDU
- 【HTML+CSS】浅谈:相对定位与绝对定位
- 1.2.1 Elevator
- 3月30发布新品,乐视能否终结彩电品牌口水战?