骑士精神——IDA*

Posted rsqppp

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了骑士精神——IDA*相关的知识,希望对你有一定的参考价值。

不说了,这玩意就是个人生题,昨天晚上各种鬼,还有变量突然变成0的坑爹事情都出现了。

 

十五步以上算-1解。。。

 

总体思路,IDA*:

1.写个估值函数,这里我写的是和目标图的理想差异

2.枚举步数,根据步数和估值来决定剪枝。

3.一点经验,估值剪枝不要严格卡在步数上,可以适当放高上限,确保答案在搜索树上,换言之就是剪枝写的鲁棒一点,确保答案完整性,再去考虑效率,当然,这一题的条件可以很显然,g步最多接近最终局面g+1步,所以很容易写出剪枝。

黏上丑陋不堪的代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 
 6 using namespace std;
 7 
 8 const int ans[5][5] =
 9 {{1,1,1,1,1},
10  {0,1,1,1,1},
11  {0,0,2,1,1},
12  {0,0,0,0,1},
13  {0,0,0,0,0},
14 };
15 int Map[5][5];
16 int flag = 0;
17 int dx[9] = {-2,-1,1,2,2,1,-1,-2};
18 int dy[9] = {-1,-2,-2,-1,1,2,2,1};
19 int gx()
20 {
21     int gx = 0;
22     for(int i = 0;i < 5;i++)
23         for(int j = 0;j < 5;j++)
24             if(Map[i][j] != ans[i][j])
25                 gx++;
26     return gx;
27 }
28 
29 void dfs(int x,int y,int s,int k)
30 {
31     if(flag ) return;
32     int g = gx();
33     if(g == 0){flag = 1;return;}
34     if(g + s > k+1) return;        //g步最多改变g+1个位置所以上限为k+1。
35     for(int i = 0;i < 8;i++)
36     {
37         int newx = x+dx[i];
38         int newy = y+dy[i];
39         if(newx<0||newx>4||newy<0||newy>4) continue;
40         swap(Map[newx][newy],Map[x][y]);
41         dfs(newx,newy,s+1,k);
42         swap(Map[newx][newy],Map[x][y]);    
43     }
44 
45 }
46 int main()
47 {
48     int T;
49     cin>>T;
50     while(T--)
51     {
52         memset(Map,0,sizeof(Map));
53         string a;
54         int sx,sy;
55         flag = 0;
56         for(int i = 0;i < 5;i++)
57         {
58             cin>>a;
59             for(int j = 0;j < 5;j++)
60             {
61                 if(a[j] == \'*\'){
62                     sx = i;
63                     sy = j;
64                     Map[i][j] = 2;
65                 }else if(a[j] >=\'0\'&&a[j] <= \'9\'){
66                     Map[i][j] = a[j]-\'0\';
67                 }
68             }
69         }
70         for(int i = 1;i <= 15;i++){
71             dfs(sx,sy,0,i);
72             if(flag){
73                 cout<<i<<endl;
74                 break;
75             }
76         }
77         if(!flag) cout<<"-1"<<endl;
78     }    
79     return 0;
80 }

就酱吧。

以上是关于骑士精神——IDA*的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ1085:[SCOI2005]骑士精神——题解+IDA*粗略讲解

埃及分数&&The Rotation Game&&骑士精神——IDA*

[SCOI2005]骑士精神

BZOJ1085_骑士精神_KEY

题解P2324 [SCOI2005]骑士精神

bzoj1085 [SCOI2005]骑士精神