题意:一个#型的棋盘,上面有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 }

浙公网安备 33010602011771号