HDU 1043 eight (Astar 八数码)
2017-05-02 08:40
344 查看
八数码问题是搜索算法中非常著名的问题,HDU这道八数码通过普通搜索无法通过,这里需要用到A* 算法或者双向广搜,这里我选择使用A* 算法来实现,借此机会学习一下A*算法
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<vector> #include<cmath> #include<map> #include<string> using namespace std; struct Node { int maze[3][3]; int h, g; int x, y; int Hash; bool operator<(const Node n1)const { return h != n1.h ? h>n1.h:g>n1.g; } bool check() { if (x >= 0 && x<3 && y >= 0 && y<3) return true; return false; } } s, u, v, tt; int HASH[9] = { 1,1,2,6,24,120,720,5040,40320 }; int destination = 322560; int vis[400000]; int pre[400000]; int way[4][2] = { { 0,1 },{ 0,-1 },{ 1,0 },{ -1,0 } }; int get_hash(Node tmp) { int a[9], k = 0; for (int i = 0; i<3; i++) for (int j = 0; j<3; j++) a[k++] = tmp.maze[i][j]; int res = 0; for (int i = 0; i<9; i++) { int k = 0; for (int j = 0; j<i; j++) if (a[j]>a[i]) k++; res += HASH[i] * k; } return res; } bool isok(Node tmp) { int a[9], k = 0; for (int i = 0; i<3; i++) for (int j = 0; j<3; j++) a[k++] = tmp.maze[i][j]; int sum = 0; for (int i = 0; i<9; i++) for (int j = i + 1; j<9; j++) if (a[j] && a[i] && a[i]>a[j]) sum++; return !(sum & 1); } int get_h(Node tmp) { int ans = 0; for (int i = 0; i<3; i++) for (int j = 0; j<3; j++) if (tmp.maze[i][j]) ans += abs(i - (tmp.maze[i][j] - 1) / 3) + abs(j - (tmp.maze[i][j] - 1) % 3); return ans; } void astar() { priority_queue<Node>que; que.push(s); while (!que.empty()) { u = que.top(); que.pop(); for (int i = 0; i<4; i++) { v = u; v.x += way[i][0]; v.y += way[i][1]; if (v.check()) { swap(v.maze[v.x][v.y], v.maze[u.x][u.y]); v.Hash = get_hash(v); if (vis[v.Hash] == -1 && isok(v)) { vis[v.Hash] = i; v.g++; pre[v.Hash] = u.Hash; v.h = get_h(v); que.push(v); } if (v.Hash == destination) return; } } } } void print() { string ans; ans.clear(); int nxt = destination; while (pre[nxt] != -1) { switch (vis[nxt]) { case 0: ans += 'r'; break; case 1: ans += 'l'; break; case 2: ans += 'd'; break; case 3: ans += 'u'; break; } nxt = pre[nxt]; } for (int i = ans.size() - 1; i >= 0; i--) putchar(ans[i]); puts(""); } int main() { std::ios::sync_with_stdio(false); std::cin.tie(0); string str; while (getline(cin,str)) { int k = 0; memset(vis, -1, sizeof(vis)); memset(pre, -1, sizeof(pre)); for (int i = 0; i<3; i++) for (int j = 0; j<3; j++) { if ((str[k] <= '9'&&str[k] >= '0') || str[k] == 'x') { if (str[k] == 'x') { s.maze[i][j] = 0; s.x = i; s.y = j; } else s.maze[i][j] = str[k] - '0'; } else j--; k++; } if (!isok(s)) { printf("unsolvable\n"); continue; } s.Hash = get_hash(s); if (s.Hash == destination) { puts(""); continue; } vis[s.Hash] = -2; s.g = 0; s.h = get_h(s); astar(); print(); } return 0; }
相关文章推荐
- HDU1043 Eight(八数码:逆向BFS打表+康托展开)题解
- poj 1077 hdu 1043 Eight 八数码问题 DBFS(双向广度优先搜索)a*算法 康拓展开
- POJ 1077 Eight && HDU 1043 Eight 八数码问题(A*算法)
- Hdu 1043 Eight (八数码问题)
- POJ1077&HDU1043 Eight 八数码第七境界 AStar hash 康托展开 最小堆优化 奇偶剪枝
- HDU 1043 Eight(经典八数码)(BFS+STL)
- hdu 1043 /poj 1077 Eight(经典八数码问题,BFS+康托展开)
- POJ1077&HDU1043 Eight 八数码第八境界 IDA* hash 康托展开 奇偶剪枝
- HDU 1043 Eight (BFS·八数码·康托展开)
- hdu 1043 Eight 经典八数码问题
- hdu 1043 Eight(8数码,第三重)
- HDU-1043 Eight 八数码问题
- HDU 1043 Eight (BFS·八数码·康托展开)
- HDU 1043 Eight(八数码第三境界|广搜+哈希+打表)
- POJ 1077(HDU 1043)Eight(八数码DBFS)
- HDU 1043 Eight 八数码
- hdu 1043/poj 1077 Eight (八数码 经典搜索题 bfs + 康托展开)
- HDU 1043 Eight(经典八数码问题)对比POJ 1077
- HDU 1043 / POJ 1077 Eight(八数码问题)
- hdu 1043 Eight(八数码问题 高级搜索: A* 搜索)