[bzoj1085][SCOI2005]骑士精神【暴力】
【题目链接】
http://www.lydsy.com/JudgeOnline/problem.php?id=1085
【题解】
dfs+剪枝即可。
剪枝的方法是,若当前状态与目标状态有个不同。那么至少还要使用步。若 ans则直接退出。
/* --------------
user Vanisher
problem bzoj-1085
----------------*/
# include <bits/stdc++.h>
# define ll long long
# define inf 0x3f3f3f3f
using namespace std;
int read(){
int tmp=0, fh=1; char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') fh=-1; ch=getchar();}
while (ch>='0'&&ch<='9'){tmp=tmp*10+ch-'0'; ch=getchar();}
return tmp*fh;
}
char tt[6][6];
int ans,n;
int mp[5][5];
const int dx[8]={1,2,2,1,-1,-2,-2,-1}, dy[8]={-2,-1,1,2,2,1,-1,-2},
o[5][5]={ 1,1,1,1,1,
0,1,1,1,1,
0,0,2,1,1,
0,0,0,0,1,
0,0,0,0,0};
int check(){
int num=0;
for (int i=0; i<5; i++)
for (int j=0; j<5; j++)
num+=(mp[i][j]!=o[i][j]);
return num;
}
void solve(int k, int x, int y){
int s=check();
if (s==0){
ans=k;
return;
}
if (k+s-1>=ans) return;
for (int t=0; t<8; t++){
int tx=x+dx[t], ty=y+dy[t];
if (tx<0||ty<0||tx>=5||ty>=5) continue;
swap(mp[x][y],mp[tx][ty]);
solve(k+1,tx,ty);
swap(mp[x][y],mp[tx][ty]);
}
}
int main(){
n=read();
for (int opt=1; opt<=n; opt++){
int x,y;
for (int i=0; i<5; i++){
scanf("\n%s",&tt[i]);
for (int j=0; j<5; j++){
if (tt[i][j]=='*') mp[i][j]=2,x=i,y=j;
else mp[i][j]=tt[i][j]-'0';
}
}
ans=16;
solve(0,x,y);
if (ans==16)
printf("%d\n",-1);
else printf("%d\n",ans);
}
return 0;
}