|
@@ -1,6 +1,13 @@
|
|
#include <cstdio>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
#include <cstring>
|
|
|
|
+#include <queue>
|
|
|
|
+#include <set>
|
|
|
|
+
|
|
|
|
+using std::priority_queue;
|
|
|
|
+using std::set;
|
|
|
|
+
|
|
|
|
+#define ABS(x) ((x) < 0 ? -(x) : (x))
|
|
|
|
|
|
const int dst = 123456780;
|
|
const int dst = 123456780;
|
|
const int S = 362880;
|
|
const int S = 362880;
|
|
@@ -70,39 +77,49 @@ int next_state(int p, char m) {
|
|
}
|
|
}
|
|
|
|
|
|
struct Node {
|
|
struct Node {
|
|
- int sta;
|
|
|
|
- int pre;
|
|
|
|
- char mov;
|
|
|
|
- Node(int sta = 0, int pre = 0, char mov = 0) : sta(sta), pre(pre), mov(mov) {}
|
|
|
|
|
|
+ int s;
|
|
|
|
+ int p;
|
|
|
|
+ int f;
|
|
|
|
+ int g;
|
|
|
|
+ int h;
|
|
|
|
+ char m;
|
|
|
|
+ Node(int s = 0, int p = 0, int f = 0, int g = 0, int h = 0, char m = 0)
|
|
|
|
+ : s(s), p(p), f(f), g(g), h(h), m(m) {}
|
|
|
|
+ bool operator<(const Node &that) const { return that.f < this->f; }
|
|
} queue[S];
|
|
} queue[S];
|
|
|
|
|
|
-int head, tail;
|
|
|
|
-
|
|
|
|
-bool used[S];
|
|
|
|
|
|
+int head;
|
|
|
|
|
|
char moves[] = "udlr";
|
|
char moves[] = "udlr";
|
|
char res[S + 1];
|
|
char res[S + 1];
|
|
|
|
|
|
-bool bfs(int s, int t) {
|
|
|
|
- head = 0, tail = 1;
|
|
|
|
|
|
+int eval_g(int s) {
|
|
|
|
+ int res = 0;
|
|
|
|
+ for (int i = 8; 0 <= i; i--) {
|
|
|
|
+ int c = s % 10;
|
|
|
|
+ if (c != 0) {
|
|
|
|
+ int x = (c - 1) / 3;
|
|
|
|
+ int y = (c - 1) % 3;
|
|
|
|
+ int cx = i / 3;
|
|
|
|
+ int cy = i % 3;
|
|
|
|
+ res += ABS(cx - x) + ABS(cy - y);
|
|
|
|
+ }
|
|
|
|
+ s /= 10;
|
|
|
|
+ }
|
|
|
|
+ return res;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+bool a_star(int s, int t) {
|
|
|
|
+ head = 0;
|
|
queue[head] = Node(s, -1);
|
|
queue[head] = Node(s, -1);
|
|
- memset(used, 0, sizeof(used));
|
|
|
|
- used[perm2no(s)] = true;
|
|
|
|
- while (head != tail) {
|
|
|
|
|
|
+ priority_queue<Node> pq;
|
|
|
|
+ pq.push(queue[head]);
|
|
|
|
+ set<int> used;
|
|
|
|
+ used.insert(s);
|
|
|
|
+ while (pq.size()) {
|
|
Node &cur = queue[head];
|
|
Node &cur = queue[head];
|
|
- if (cur.sta == t) return true;
|
|
|
|
- for (int i = 0; i < 4; i++) {
|
|
|
|
- char m = moves[i];
|
|
|
|
- int nxt = next_state(cur.sta, m);
|
|
|
|
- if (nxt == -1) continue;
|
|
|
|
- int no = perm2no(nxt);
|
|
|
|
- if (used[no]) continue;
|
|
|
|
- queue[tail++] = Node(nxt, head, m);
|
|
|
|
- used[no] = true;
|
|
|
|
- }
|
|
|
|
head++;
|
|
head++;
|
|
}
|
|
}
|
|
- return false;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
int main() {
|
|
int main() {
|
|
@@ -112,11 +129,11 @@ int main() {
|
|
if (perm[i] == 'x') perm[i] = '0';
|
|
if (perm[i] == 'x') perm[i] = '0';
|
|
}
|
|
}
|
|
int src = atoi(perm);
|
|
int src = atoi(perm);
|
|
- if (bfs(src, dst)) {
|
|
|
|
|
|
+ if (a_star(src, dst)) {
|
|
int pos = head, i = 0;
|
|
int pos = head, i = 0;
|
|
do {
|
|
do {
|
|
- res[i++] = queue[pos].mov;
|
|
|
|
- pos = queue[pos].pre;
|
|
|
|
|
|
+ res[i++] = queue[pos].m;
|
|
|
|
+ pos = queue[pos].p;
|
|
} while (pos != -1);
|
|
} while (pos != -1);
|
|
for (int j = i - 1; 0 <= j; j--) printf("%c", res[j]);
|
|
for (int j = i - 1; 0 <= j; j--) printf("%c", res[j]);
|
|
printf("\n");
|
|
printf("\n");
|