POJ 2286 IDA* 算法

首先附上题目链接: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 } 
View Code
原文地址:https://www.cnblogs.com/yuluoluo/p/8653478.html