|
@@ -0,0 +1,127 @@
|
|
|
+#include <cstdio>
|
|
|
+#include <cstdlib>
|
|
|
+#include <cstring>
|
|
|
+
|
|
|
+const int dst = 123456780;
|
|
|
+const int S = 362880;
|
|
|
+const int frac[9] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320};
|
|
|
+
|
|
|
+int perm2no(int p) {
|
|
|
+ char perm[10];
|
|
|
+ sprintf(perm, "%09d", p);
|
|
|
+ bool used[9] = {};
|
|
|
+ int n = 0;
|
|
|
+ for (int i = 0; i < 9; i++) {
|
|
|
+ for (int j = perm[i] - '1'; 0 <= j; j--) {
|
|
|
+ if (used[j]) continue;
|
|
|
+ n += frac[8 - i];
|
|
|
+ }
|
|
|
+ used[perm[i] - '0'] = true;
|
|
|
+ }
|
|
|
+ return n;
|
|
|
+}
|
|
|
+
|
|
|
+int no2perm(int n) {
|
|
|
+ char perm[10];
|
|
|
+ bool used[9] = {};
|
|
|
+ for (int i = 0; i < 9; i++) {
|
|
|
+ int j = n / frac[8 - i];
|
|
|
+ n %= frac[8 - i];
|
|
|
+ for (int k = 0; k < 9; k++) {
|
|
|
+ if (used[k]) continue;
|
|
|
+ if (j-- == 0) {
|
|
|
+ used[k] = true;
|
|
|
+ perm[i] = k + '0';
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return atoi(perm);
|
|
|
+}
|
|
|
+
|
|
|
+int next_state(int p, char m) {
|
|
|
+ char perm[10];
|
|
|
+ sprintf(perm, "%09d", p);
|
|
|
+ int i = 0;
|
|
|
+ while (perm[i] != '0') i++;
|
|
|
+ switch (m) {
|
|
|
+ case 'u':
|
|
|
+ if (i < 3) return -1;
|
|
|
+ perm[i] = perm[i - 3];
|
|
|
+ perm[i - 3] = '0';
|
|
|
+ return atoi(perm);
|
|
|
+ case 'd':
|
|
|
+ if (8 < i + 3) return -1;
|
|
|
+ perm[i] = perm[i + 3];
|
|
|
+ perm[i + 3] = '0';
|
|
|
+ return atoi(perm);
|
|
|
+ case 'l':
|
|
|
+ if (i % 3 == 0) return -1;
|
|
|
+ perm[i] = perm[i - 1];
|
|
|
+ perm[i - 1] = '0';
|
|
|
+ return atoi(perm);
|
|
|
+ case 'r':
|
|
|
+ if ((i + 1) % 3 == 0) return -1;
|
|
|
+ perm[i] = perm[i + 1];
|
|
|
+ perm[i + 1] = '0';
|
|
|
+ return atoi(perm);
|
|
|
+ }
|
|
|
+ return -1;
|
|
|
+}
|
|
|
+
|
|
|
+struct Node {
|
|
|
+ int sta;
|
|
|
+ int pre;
|
|
|
+ char mov;
|
|
|
+ Node(int sta = 0, int pre = 0, char mov = 0) : sta(sta), pre(pre), mov(mov) {}
|
|
|
+} queue[S];
|
|
|
+
|
|
|
+int head, tail;
|
|
|
+
|
|
|
+bool used[S];
|
|
|
+
|
|
|
+char moves[] = "udlr";
|
|
|
+char res[S + 1];
|
|
|
+
|
|
|
+bool bfs(int s, int t) {
|
|
|
+ head = 0, tail = 1;
|
|
|
+ queue[head] = Node(s, -1);
|
|
|
+ memset(used, 0, sizeof(used));
|
|
|
+ used[perm2no(s)] = true;
|
|
|
+ while (head != tail) {
|
|
|
+ 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++;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+int main() {
|
|
|
+ char perm[10];
|
|
|
+ for (int i = 0; i < 9; i++) {
|
|
|
+ scanf("%s", &perm[i]);
|
|
|
+ if (perm[i] == 'x') perm[i] = '0';
|
|
|
+ }
|
|
|
+ int src = atoi(perm);
|
|
|
+ if (bfs(src, dst)) {
|
|
|
+ int pos = head, i = 0;
|
|
|
+ do {
|
|
|
+ res[i++] = queue[pos].mov;
|
|
|
+ pos = queue[pos].pre;
|
|
|
+ } while (pos != -1);
|
|
|
+ for (int j = i - 1; 0 <= j; j--) printf("%c", res[j]);
|
|
|
+ printf("\n");
|
|
|
+ } else {
|
|
|
+ printf("unsolvable\n");
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|