[SCOI2005]骑士精神

 这是一道非常好的,A*模板题。。。

主要思路是通过理想最优情况剪枝。。。

呆码:

#include<iostream>
#include<cstdio>
using namespace std;

int n=5,ans,T,X,Y;
char ch[11][11];
char check[6][6]={
    '0','0','0','0','0','0',
    '0','1','1','1','1','1',
    '0','0','1','1','1','1',
    '0','0','0','*','1','1',
    '0','0','0','0','0','1',
    '0','0','0','0','0','0',
};
int lx[9]={0,-2,-2,-1,-1,1,1,2,2};
int ly[9]={0,-1,1,-2,2,-2,2,-1,1};

inline int best()
{
    int tot=0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            if(ch[i][j]!=check[i][j]) tot++;
    return tot;
}

inline void dfs(int x,int y,int st,int last)
{
    int l=best();
    if(st+l>16) return;
    if(st>=ans) return;
    if(l==0) { ans=st; return; }
    for(int i=1;i<=8;i++)
    {
        int xx=x+lx[i];
        int yy=y+ly[i];
        if(xx<1 || xx>5 || yy<1 || yy>5)
            continue;
        if(i+last!=9)
        {
            swap(ch[xx][yy],ch[x][y]);
            dfs(xx,yy,st+1,i);
            swap(ch[xx][yy],ch[x][y]);
        }
    }
}

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        for(int i=1;i<=n;i++)
            scanf("%s",ch[i]+1);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if(ch[i][j]=='*') X=i,Y=j;
        ans=17;
        dfs(X,Y,0,0);
        printf("%d
",ans==17 ? -1 : ans);
    }
}
代码
原文地址:https://www.cnblogs.com/zzzyc/p/9257363.html