您的位置:首页 > 其它

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

2017-05-21 19:08 483 查看

题意

给定一个初始状态,用最少步数变成如下图案,如果超过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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: