IDA*——BZOJ1085/Luogu2324 [SCOI2005] 骑士精神

来源:互联网 发布:淘宝直通车删除计划 编辑:程序博客网 时间:2024/06/05 07:17

http://www.lydsy.com/JudgeOnline/problem.php?id=1085
https://www.luogu.org/problem/show?pid=2324
从ZJOI2017讲课学来的新东西。。。
这题也就是启发式搜索(或者称A*)
。。哦不对,是IDA*(迭代加深启发式搜索)

我们找到空位置以后直接搜索状态直到目标状态
但是显然的,暴搜是过不掉这题的
一个最优性剪枝:计算不在目标位置的骑士个数m,如果m不足以在15步范围内把所有骑士归位,剪枝(写出这个DFS就升级成为A*了)
但是这样好像还是会T啊(不过我没试过)
题中有说,步数大于15步输出-1,所以最深层数是15
有限制层数而且那么小为什么不用迭代加深呢
于是我们就可以把上面的A*优化成IDA*
也就是限制层数
这个时候把剪枝内容改一下:计算不在目标位置的骑士个数m,如果m不足以在k步范围内把所有骑士归位,剪枝(k是限制层数)
然后就可以愉快地AC了
后注:哦对,这题数据luogu中没有答案为0的情况,其实0也可以是答案当输入状态为最终状态时
感谢lc233提醒
我一开始的程序是可以被卡掉的,改好的程序在下面

#include<bits/stdc++.h>using namespace std;int a[10][10];const int dx[9]={0,1,1,-1,-1,2,2,-2,-2};const int dy[9]={0,2,-2,2,-2,1,-1,1,-1};bool flag;const int b[6][6]={{0,0,0,0,0,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}};inline bool check(int a[10][10]){//目标状态判定    for(int i=1;i<=5;i++)        for(int j=1;j<=5;j++)if(a[i][j]!=b[i][j])return 0;    return 1;   }inline bool A(int a[10][10],int p,int k){//最优性剪枝    int m=0;    for(int i=1;i<=5;i++)        for(int j=1;j<=5;j++)if(a[i][j]!=b[i][j]){            m++;            if(m+p>k)return 0;        }    return 1;}inline void dfs(int p,int a[10][10],int k,int x,int y){    if(flag)return;    if(p==k){        if(check(a))flag=1;        return;    }    for(int i=1;i<=8;i++){        int xx=x+dx[i],yy=y+dy[i];        if(xx<1||xx>5||yy<1||yy>5)continue;        swap(a[x][y],a[xx][yy]);        if(A(a,p,k))dfs(p+1,a,k,xx,yy);        swap(a[x][y],a[xx][yy]);    }}int main(){    int t,x,y;scanf("%d",&t);    while(t--){        flag=0;        for(int i=1;i<=5;i++){            char c[10];scanf("%s",c+1);            for(int j=1;j<=5;j++)                if(c[j]=='*')a[i][j]=2,x=i,y=j;                else a[i][j]=c[j]-'0';        }        for(int i=0;i<=15;i++){//i限制层数            dfs(0,a,i,x,y);            if(flag){                printf("%d\n",i);                break;            }        }        if(flag)continue;        printf("-1\n");    }    return 0;}
1 0
原创粉丝点击