【BZOJ1085】【SCOI2005】骑士精神(IDA*)

来源:互联网 发布:linux 文件用户组 编辑:程序博客网 时间:2024/06/14 21:13

题目链接:https://www.luogu.org/problem/show?pid=2324
题解:
经典迭代加深搜索
考虑到步数最大只有15步,用IDA*比较好,估价函数设为有几个点未到达目标位置,进行搜索即可

//by sdfzchy#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int a[6][6];int sx,sy;int map[6][6]={ 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0,-1, 1, 1, 1, 1, 0,-1,-1, 2, 1, 1, 0,-1,-1,-1,-1, 1, 0,-1,-1,-1,-1,-1};int xx[8]={1,1,2,2,-1,-1,-2,-2};int yy[8]={2,-2,1,-1,2,-2,1,-1};int tmp[6][6];bool check(){    for(int i=1;i<=5;i++)        for(int j=1;j<=5;j++)        if(tmp[i][j]!=map[i][j]) return 0;    return 1;   }bool calc(int cur,int dep){    for(int i=1;i<=5;i++)        for(int j=1;j<=5;j++)            if(tmp[i][j]!=map[i][j]) cur++;    return cur<=dep;    }int tot;bool dfs(int x,int y,int cur,int dep){    if(cur==dep) return check();    for(int i=0;i<8;i++)    {        int nx=x+xx[i];        int ny=y+yy[i];        if(nx<1||nx>5||ny<1||ny>5) continue;        swap(tmp[x][y],tmp[nx][ny]);        if(calc(cur,dep)) if(dfs(nx,ny,cur+1,dep)) return true;        swap(tmp[x][y],tmp[nx][ny]);    }    return 0;}int main(){    int T;    scanf("%d",&T);    while(T--)    {        char s[10];        for(int i=1;i<=5;i++)        {            scanf("%s",s+1);            for(int j=1;j<=5;j++)                if(s[j]=='1') a[i][j]=1;                else if(s[j]=='0') a[i][j]=-1;                else sx=i,sy=j,a[i][j]=2;        }        for(int dep=0;dep<=16;dep++)        {            if(dep==16) {puts("-1");break;}            for(int i=1;i<=5;i++)   for(int j=1;j<=5;j++)   tmp[i][j]=a[i][j];              if(dfs(sx,sy,0,dep)) {printf("%d\n",dep);break;}        }    }    return 0;}