main.cc 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <cstring>
  4. const int dst = 123456780;
  5. const int S = 362880;
  6. const int frac[9] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320};
  7. int perm2no(int p) {
  8. char perm[10];
  9. sprintf(perm, "%09d", p);
  10. bool used[9] = {};
  11. int n = 0;
  12. for (int i = 0; i < 9; i++) {
  13. for (int j = perm[i] - '1'; 0 <= j; j--) {
  14. if (used[j]) continue;
  15. n += frac[8 - i];
  16. }
  17. used[perm[i] - '0'] = true;
  18. }
  19. return n;
  20. }
  21. int no2perm(int n) {
  22. char perm[10];
  23. bool used[9] = {};
  24. for (int i = 0; i < 9; i++) {
  25. int j = n / frac[8 - i];
  26. n %= frac[8 - i];
  27. for (int k = 0; k < 9; k++) {
  28. if (used[k]) continue;
  29. if (j-- == 0) {
  30. used[k] = true;
  31. perm[i] = k + '0';
  32. break;
  33. }
  34. }
  35. }
  36. return atoi(perm);
  37. }
  38. int next_state(int p, char m) {
  39. char perm[10];
  40. sprintf(perm, "%09d", p);
  41. int i = 0;
  42. while (perm[i] != '0') i++;
  43. switch (m) {
  44. case 'u':
  45. if (i < 3) return -1;
  46. perm[i] = perm[i - 3];
  47. perm[i - 3] = '0';
  48. return atoi(perm);
  49. case 'd':
  50. if (8 < i + 3) return -1;
  51. perm[i] = perm[i + 3];
  52. perm[i + 3] = '0';
  53. return atoi(perm);
  54. case 'l':
  55. if (i % 3 == 0) return -1;
  56. perm[i] = perm[i - 1];
  57. perm[i - 1] = '0';
  58. return atoi(perm);
  59. case 'r':
  60. if ((i + 1) % 3 == 0) return -1;
  61. perm[i] = perm[i + 1];
  62. perm[i + 1] = '0';
  63. return atoi(perm);
  64. }
  65. return -1;
  66. }
  67. struct Node {
  68. int sta;
  69. int pre;
  70. char mov;
  71. Node(int sta = 0, int pre = 0, char mov = 0) : sta(sta), pre(pre), mov(mov) {}
  72. } queue[S];
  73. int head, tail;
  74. bool used[S];
  75. char moves[] = "udlr";
  76. char res[S + 1];
  77. bool bfs(int s, int t) {
  78. head = 0, tail = 1;
  79. queue[head] = Node(s, -1);
  80. memset(used, 0, sizeof(used));
  81. used[perm2no(s)] = true;
  82. while (head != tail) {
  83. Node &cur = queue[head];
  84. if (cur.sta == t) return true;
  85. for (int i = 0; i < 4; i++) {
  86. char m = moves[i];
  87. int nxt = next_state(cur.sta, m);
  88. if (nxt == -1) continue;
  89. int no = perm2no(nxt);
  90. if (used[no]) continue;
  91. queue[tail++] = Node(nxt, head, m);
  92. used[no] = true;
  93. }
  94. head++;
  95. }
  96. return false;
  97. }
  98. int main() {
  99. char perm[10];
  100. for (int i = 0; i < 9; i++) {
  101. scanf("%s", &perm[i]);
  102. if (perm[i] == 'x') perm[i] = '0';
  103. }
  104. int src = atoi(perm);
  105. if (bfs(src, dst)) {
  106. int pos = head, i = 0;
  107. do {
  108. res[i++] = queue[pos].mov;
  109. pos = queue[pos].pre;
  110. } while (pos != -1);
  111. for (int j = i - 1; 0 <= j; j--) printf("%c", res[j]);
  112. printf("\n");
  113. } else {
  114. printf("unsolvable\n");
  115. }
  116. return 0;
  117. }