dengxinyi 6 anni fa
parent
commit
6d3f381636
1 ha cambiato i file con 127 aggiunte e 0 eliminazioni
  1. 127 0
      poj/1077.eight/main.cc

+ 127 - 0
poj/1077.eight/main.cc

@@ -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;
+}