【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 }
AC Code

 

posted @ 2019-08-08 19:18  AD_shl  阅读(244)  评论(0编辑  收藏  举报