[IDA*] BZOJ1085: [SCOI2005]骑士精神

来源:互联网 发布:java可变参数不传入 编辑:程序博客网 时间:2024/05/21 10:09

题意

给定一个初始状态,用最少步数变成如下图案,如果超过15步输出-1。
这里写图片描述

题解

IDA*经典题。
显然是个搜索题,看到”超过15步输出-1”,就能想到迭代加深搞,IDA*特别适合这题。
估价函数很简单,统计一下几个位置上不是正确的颜色即可。
如果把中间是否是空白也加入统计的话,要注意估价结果可能会大于实际代价(最后一步之前h=2>1),所以需要减一。

#include<cstdio>#include<algorithm>using namespace std;const int lst[5][5]={{1,1,1,1,1},                     {0,1,1,1,1},                     {0,0,-1,1,1},                     {0,0,0,0,1},                     {0,0,0,0,0}};const int flag[8][2]={{-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1}};int _test,ans,a[10][10];inline int H(){    int res=0;    for(int i=0;i<=4;i++) for(int j=0;j<=4;j++) res+=a[i][j]!=lst[i][j];    return res;}bool IDAstar(int step){    int now_h=H();    if(step+now_h-1>ans) return false;    if(!now_h) return true;    int x,y; for(int i=0;i<=4;i++) for(int j=0;j<=4;j++) if(a[i][j]==-1) x=i, y=j;    for(int i=0;i<=7;i++){        int xx=x+flag[i][0], yy=y+flag[i][1];        if(!(xx>=0&&xx<=4&&yy>=0&&yy<=4)) continue;        swap(a[xx][yy],a[x][y]);        bool pd=IDAstar(step+1);         swap(a[xx][yy],a[x][y]);        if(pd) return true;    }    return false;}int main(){    freopen("bzoj1085.in","r",stdin);    freopen("bzoj1085.out","w",stdout);    scanf("%d",&_test);    while(_test--){        for(int i=0;i<=4;i++){            while(getchar()!='\n');            for(int j=0;j<=4;j++){                char ch=getchar();                if(ch=='*') a[i][j]=-1;                       else a[i][j]=ch-'0';             }        }        for(ans=0;ans<=16;ans++)         if(IDAstar(0)) break;        if(ans>15) printf("-1\n"); else printf("%d\n",ans);    }}
原创粉丝点击