题意:一个#型的棋盘,上面有1、2、3各8个,要求通过8种操作使得最后中间的八个格子数字相同。

题解:IDA*搜索,首先,每个格子有三种状态,总共有3^24种状态,即使通过1、2、3都只有8个排除一些内存也是不够的,相反,此题给了15s的时限,便可以用时间效率不如bfs,但是空间上完爆bfs的IDA*了。

   1、记录八种旋转的改变数组位置,然后在设定的depth范围内dfs。

   2、两个剪枝:a)当前操作是上一次操作的逆操作。b)当前状态最好情况也无法在depth之内完成任务,即使中间8个格子中最多的数字在最好情况下凑成目标态也超过了depth。

View Code
 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 using namespace std;
 5 int rot[8][7]=
 6 {
 7     0,2,6,11,15,20,22,//A
 8     1,3,8,12,17,21,23,//B
 9     10,9,8,7,6,5,4,//C
10     19,18,17,16,15,14,13,//D
11     23,21,17,12,8,3,1,//E
12     22,20,15,11,6,2,0,//F
13     13,14,15,16,17,18,19,//G
14     4,5,6,7,8,9,10//H
15 };
16 int res[]={5,4,7,6,1,0,3,2};
17 int depth;
18 bool check(char s[])
19 {
20     char ch=s[6];
21     for(int i=0;i<3;i++)
22         if(ch!=s[i+6]||ch!=s[15+i])
23             return false;
24     return ch==s[11]&&ch==s[12];
25 }
26 void rotate(int k,char s[])
27 {
28     char ch=s[rot[k][0]];
29     for(int i=0;i<6;i++)
30         s[rot[k][i]]=s[rot[k][i+1]];
31     s[rot[k][6]]=ch;
32 }
33 bool IDAstar(int k,char st[],char op[],int la)
34 {
35     int cnt[4];
36     cnt[1]=cnt[2]=cnt[3]=0;
37     for(int i=0;i<3;i++)
38         cnt[st[i+6]-'0']++,cnt[st[15+i]-'0']++;
39     cnt[st[11]-'0']++,cnt[st[12]-'0']++;
40     cnt[0]=max(max(cnt[1],cnt[2]),cnt[3]);
41     if(k+8-cnt[0]>=depth)
42         return false;
43     for(int i=0;i<8;i++)
44     {
45         if(la!=-1&&res[i]==la)
46             continue;
47         op[k]='A'+i;
48         rotate(i,st);
49         if(check(st))
50         {
51             op[k+1]='\0';
52             return true;
53         }
54         else if(IDAstar(k+1,st,op,i))
55             return true;
56         rotate(res[i],st);
57     }
58     return false;
59 }
60 int main()
61 {
62     char ch;
63     while(scanf(" %c",&ch),ch!='0')
64     {
65         char st[25];
66         st[0]=ch;
67         for(int i=1;i<24;i++)
68             scanf(" %c",&st[i]);
69         depth=1;
70         if(check(st))
71         {
72             printf("No moves needed\n%c\n",st[6]);
73         }
74         else
75         {
76             char op[200];
77             op[0]='\0';
78             while(!IDAstar(0,st,op,-1))
79                 depth++;
80             printf("%s\n%c\n",op,st[6]);
81         }
82     }
83     return 0;
84 }