[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 }