【POJ2286】The Rotation Game
Solution
由于搜索量较大,我们采用IDA*算法求解。
按照迭代加深搜索的基本方法,我们限制搜索深度,然后寻找在当前限制下是否存在解。
为了提高算法效率,我们设计A*函数作为估价,返回目标位置与实际不同的个数即可。
在搜索时我们不妨记录上一步搜索的分支,以免执行上一次操作的逆操作。
本题难点主要在于对读入数据的处理和执行旋转操作。
Code
1 #include <cstdio> 2 #include <iostream> 3 inline int read() { 4 int ret = 0, op = 1; 5 char c = getchar(); 6 while (!isdigit(c)) { 7 if (c == '-') op = -1; 8 c = getchar(); 9 } 10 while (isdigit(c)) { 11 ret = ret * 10 + c - '0'; 12 c = getchar(); 13 } 14 return ret * op; 15 } 16 const int center[10] = {6, 7, 8, 11, 12, 15, 16, 17}; 17 const int all[80][70] = { 18 {0, 2, 6, 11, 15, 20, 22}, // A 19 {1, 3, 8, 12, 17, 21, 23}, // B 20 {10, 9, 8, 7, 6, 5, 4}, // C 21 {19, 18, 17, 16, 15, 14, 13}, // D 22 {23, 21, 17, 12, 8, 3, 1}, // E 23 {22, 20, 15, 11, 6, 2, 0}, // F 24 {13, 14, 15, 16, 17, 18, 19}, // G 25 {4, 5, 6, 7, 8, 9, 10} // H 26 }; 27 int a[50]; 28 char ans[100]; 29 inline int check() { 30 for (register int i = 1; i < 8; ++i) 31 if (a[center[i]] != a[center[0]]) return 0; 32 return 1; 33 } 34 inline int A_star() { 35 int ret = 100; 36 for (register int i = 1; i < 4; ++i) { 37 int sum = 0; 38 for (register int j = 0; j < 8; ++j) 39 if (i != a[center[j]]) sum++; 40 ret = std :: min(ret, sum); 41 } 42 return ret; 43 } 44 inline void rotate(int op) { 45 int fir = a[all[op][0]]; 46 for (register int i = 0; i < 6; ++i) a[all[op][i]] = a[all[op][i + 1]]; 47 a[all[op][6]] = fir; 48 } 49 int dfs(int now, int maxdep, int last) { 50 if (now == maxdep) return check(); 51 if (now + A_star() > maxdep) return 0; 52 for (register int i = 0; i < 8; ++i) { 53 if (last == -1); 54 else if (last % 2 == 1 && i == (last + 3) % 8) continue ; 55 else if (last % 2 == 0 && i == (last + 5) % 8) continue ; 56 ans[now] = i + 'A'; 57 rotate(i); 58 if (dfs(now + 1, maxdep, i)) return 1; 59 if (i & 1) rotate((i + 3) % 8); 60 else rotate((i + 5) % 8); 61 } 62 return 0; 63 } 64 int main() { 65 while (1) { 66 a[0] = read(); 67 if (!a[0]) return 0; 68 for (register int i = 1; i < 24; ++i) a[i] = read(); 69 if (check()) { 70 puts("No moves needed"); 71 printf("%d\n", a[center[0]]); 72 continue ; 73 } 74 register int i; 75 for (i = 0; !dfs(0, i, -1); ++i); 76 ans[i] = '\0'; 77 printf("%s\n", ans); 78 printf("%d\n", a[center[0]]); 79 } 80 return 0; 81 }