您的位置:首页 > 其它

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*搜索。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: