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;
}
View Code

 

posted @ 2017-09-13 18:55  啊宸  阅读(57)  评论(0编辑  收藏