【BZOJ1085】【SCOI2005】骑士精神(A*暴搜)

题目描述

传送门

题解

启发式搜索,估价函数可以设为当前状态和目标状态有多少个不同。
刚开始觉得比较奇怪,因为这里其实是按步数搜索。我的理解是应该是每一次搜索用估价函数计算出下一步哪一个得到正确结果的可能性最大,优先搜索可能性最大的。但是这道题貌似不适用。
可能是因为现在对A*的理解还不是很透彻,还需要慢慢消化。
明白之后补上。

代码

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int end[6][6]={{0},
            {0,1,1,1,1,1},
            {0,0,1,1,1,1},
            {0,0,0,2,1,1},
            {0,0,0,0,0,1},
            {0,0,0,0,0,0}};
int sx[8]={1,1,-1,-1,2,2,-2,-2};
int sy[8]={2,-2,2,-2,1,-1,1,-1};

int T,now[6][6],x,y,k;
bool flag;
char ch;

inline bool judge(){
    for (int i=1;i<=5;++i)
      for (int j=1;j<=5;++j)
        if (end[i][j]!=now[i][j]) return false;
    return true;
}

inline bool eva(int step){
    int tot=0;
    for (int i=1;i<=5;++i)
      for (int j=1;j<=5;++j)
        if (now[i][j]!=end[i][j]){
            tot++;
            if (step+tot>k) return false;
        }
    return true;
}

inline void dfs(int step,int x,int y){
    if (step==k&&judge()){
        flag=true;
        return;
    }
    if (flag) return;
    for (int i=0;i<8;++i){
        int nowx=x+sx[i],nowy=y+sy[i];
        if (nowx>0&&nowx<=5&&nowy>0&&nowy<=5){
            swap(now[x][y],now[nowx][nowy]);
            if (eva(step)) 
              dfs(step+1,nowx,nowy);
            swap(now[x][y],now[nowx][nowy]);
        }
    }
}

int main(){
    scanf("%d",&T);
    while (T--){
        for (int i=1;i<=5;++i)
          for (int j=1;j<=5;++j){
            ch=getchar();
            while (ch!='1'&&ch!='0'&&ch!='*') ch=getchar();
            if (ch=='*'){
                x=i; y=j;
                now[i][j]=2;
            }
            else now[i][j]=ch-'0';
          }
        for (k=1;k<=15;++k){
            flag=false;
            dfs(0,x,y);
            if (flag){
                printf("%d\n",k);
                break;
            }
        }
        if (!flag) printf("-1\n");
        else flag=false;
    }
}

总结

①字符串读入的时候注意一下。

你可能感兴趣的:(搜索,a,bzoj)