[bzoj1085]骑士精神

容易发现从当前状态到目标最少要跳不同的位置数-1,然后以此为估价函数IDA*(444ms,即先枚举答案再A*)或A*(664ms)即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int t,x,y,ans,dx[8]={-2,-2,-1,-1,1,1,2,2},dy[8]={-1,1,-2,2,-2,2,-1,1};
 4 char mb[11][11],s[11][11];
 5 int gj(){
 6     int sum=0;
 7     for(int i=0;i<5;i++)
 8         for(int j=0;j<5;j++)sum+=(mb[i][j]!=s[i][j]);
 9     return sum-1;
10 }
11 bool dfs(int x,int y,int sum){
12     if (gj()>sum)return 0;
13     if (gj()<0)return 1;
14     for(int i=0;i<8;i++){
15         int xx=x+dx[i],yy=y+dy[i];
16         if ((xx<0)||(yy<0)||(xx>4)||(yy>4))continue;
17         swap(s[x][y],s[xx][yy]);
18         if (dfs(xx,yy,sum-1)){
19             swap(s[x][y],s[xx][yy]);
20             return 1;
21         }
22         swap(s[x][y],s[xx][yy]);
23     }
24     return 0;
25 }
26 int main(){
27     for(int i=0;i<5;i++)
28         for(int j=0;j<5;j++)mb[i][j]='0'+(i<j);
29     mb[0][0]=mb[1][1]='1';
30     mb[2][2]='*';
31     scanf("%d",&t);
32     while (t--){
33         for(int i=0;i<5;i++){
34             scanf("%s",s[i]);
35             for(int j=0;j<5;j++)
36                 if (s[i][j]=='*'){
37                     x=i;
38                     y=j;
39                 }
40         }
41         bool flag=0;
42         for(int i=0;i<16;i++)
43             if (dfs(x,y,i)){
44                 printf("%d\n",i);
45                 flag=1;
46                 break;
47             }
48         if (!flag)printf("-1\n");
49     }
50 }
View Code

 

posted @ 2019-11-05 09:27  PYWBKTDA  阅读(126)  评论(0编辑  收藏  举报