main.cc 2.8 KB

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