首先附上题目链接:http://poj.org/problem?id=2286
我的第一道IDA* 题,感觉挺不错的。IDA*具体参考大神的博客:https://blog.csdn.net/Davenny/article/details/74938794
下面是代码:
1 #include <stdio.h> 2 3 using namespace std; 4 /* 5 IDA* 算法 迭代加深搜索 + 预估剪枝 6 */ 7 int deep = 0; 8 int a[25]; 9 10 int p[8] = {6,7,8,11,12,15,16,17};//中间8个所对应的序号 11 int rev[8] = {5,4,7,6,1,0,3,2};//A-F B-E...反着移动 12 int ans[110];//存储答案的路径。 13 int op[8][7] = {0,2,6,11,15,20,22, 14 1,3,8,12,17,21,23, 15 10,9,8,7,6,5,4, 16 19,18,17,16,15,14,13, 17 23,21,17,12,8,3,1, 18 22,20,15,11,6,2,0, 19 13,14,15,16,17,18,19, 20 4,5,6,7,8,9,10};//8种操作的原始顺序 对应ABCDEFGH 21 //预估函数,用来剪枝 22 //要求是使中间八个相同 23 //而每次移动最多增加一个相同的数。 24 //所以最少预估移动此时就是 == (8 - 出现次数最多的数的次数) 25 int Estimate() 26 { 27 int x[]={0,0,0,0}; 28 for (int i=0;i<8;++i)//统计出中心点1,2,3的个数 29 x[a[p[i]]]++; 30 int an = 0; 31 for (int i=1;i<4;++i) 32 if (x[i] > an ) an = x[i];//记录下次数最多的数的次数 33 return 8 - an;//这样就得到了预估移动此时 34 } 35 //变换函数 36 void change(int n) 37 { 38 int t = a[op[n][0]];//在变换移动的时候,得保存头数据,防止在后面数据前移时覆盖掉 39 for (int i=0;i<6;i++) 40 a[op[n][i]]=a[op[n][i+1]]; 41 a[op[n][6]] = t; 42 } 43 44 int dfs (int cur)//当前深度 45 { 46 if(cur == deep) //当前深度等于最大深度 47 { 48 if (Estimate()==0) return cur;//找到了答案,并返回步骤个数. 49 return 0; 50 } 51 if (cur + Estimate() > deep ) return 0; 52 for (int i=0;i<8;++i) //一次执行这八个操作。 53 { 54 change(i);//按照 i 操作进行变换。 55 if (Estimate() + cur <= deep)//说明有可能找到答案,可以递归 56 { int m = 0; 57 ans[cur] = i; 58 if (m = dfs(cur+1)) {return m;};//向下递归,同时判断是否找到答案。 59 //找到了答案,停止搜索。 60 } 61 change(rev[i]);//变换回来,然后继续试探其他变换操作。 62 } 63 return 0; 64 } 65 66 //答案输出 67 void putans (int m) 68 { 69 for (int i = 0;i<m;++i) 70 printf ("%c",ans[i]+'A'); 71 printf (" %d ",a[15]); 72 } 73 74 int main () 75 { int m = 0 ; 76 while(scanf ("%d",&a[0])==1 && a[0]) 77 { 78 for (int i = 1;i <= 23;++i) 79 scanf ("%d",&a[i]); 80 //开始迭代加深 81 if (Estimate()==0) 82 {printf("No moves needed %d ",a[17]);continue;}//事先判断下是否已经8个相同的了 83 deep = 0; 84 while(true) 85 { 86 deep++; 87 if(m = dfs(0)) { break;} 88 } 89 putans (m); 90 } 91 return 0; 92 }