HDU 1043 搜索 A*算法

来源:互联网 发布:zealer续航数据库 编辑:程序博客网 时间:2024/06/05 10:04
#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*搜索。

0 0