BZOJ 1085 [SCOI2005]骑士精神
据说是A_star的裸题,感觉就是爆搜剪枝。
//Twenty
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
int ans,T,x,y;
char a[6][6],b[6][6]={{"11111"}, {"01111"}, {"00*11"}, {"00001"}, {"00000"}};
int xx[10]={-1,-1,1,1,-2,-2,2,2},yy[10]={-2,2,-2,2,-1,1,1,-1};
int ok(int i,int j) {return i>=0&&i<5&&j>=0&&j<5;}
int check(char a[][6],char b[][6]) {
int res=0;
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
if(a[i][j]!=b[i][j]) res++;
return res;
}
int same(char a[][6],char b[][6]) {
int res=0;
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
if(a[i][j]!=b[i][j]) return 0;
return 1;
}
void dfs(int dep) {
if(same(a,b)) {
ans=min(ans,dep);
return;
}
if(dep>min(ans,15)) return;
for(int i=0;i<5;i++) for(int j=0;j<5;j++) if(a[i][j]=='*') x=i,y=j;
for(int i=0;i<8;i++) {
x+=xx[i]; y+=yy[i];
if(ok(x,y)){
swap(a[x][y],a[x-xx[i]][y-yy[i]]);
if(check(a,b)+dep<=ans) dfs(dep+1);
swap(a[x][y],a[x-xx[i]][y-yy[i]]);
}
x-=xx[i]; y-=yy[i];
}
}
int main() {
scanf("%d",&T);
while(T--) {
for(int i=0;i<5;i++)
scanf("%s",a[i]);
ans=16;
dfs(0);
if(ans==16) printf("-1\n");
else printf("%d\n",ans);
}
return 0;
}