[SCOI2005]骑士精神(IDA*)

题面:[SCOI2005]骑士精神

对于这道题,我们第一眼:\(bfs\)爆搜

第二眼:发现事情没这么简单:这是道省选题

第三眼:仔细一想,直接\(bfs\)难道不会被卡爆吗??

第四眼:发现题目中有:“如果能在15步以内(包括15步)到达目标状态,则输出步数,否则输出-1

好的,\(IDA\)*:启发式迭代加深

\(IDA\)*是什么?

其实就是在\(A\)*的基础上加上迭代加深

还不知道\(A\)*的同学点这里

迭代加深其实就是每次搜索的时候限制你的搜索深度,使你的搜索树的深度保持在一个较为合理的地方,使你的时间不会爆炸,这样就可以使你在全局搜索的深度很大而答案深度很小的情况下(也是使用\(IDA\)*的条件)快速得出答案

在这道题中,明显可以看出,答案深度\(<=15\),所以我们考虑使用\(IDA\)*,在每次搜索是加上限制深度条件\(maxstep\),如果当前搜索深度\(step==maxstep\),就返回答案

作为\(A\)*的精髓,估价函数\(g(x)\)当然是我们思考的主要对象

我们可以发现,这道题给出了棋盘的目标布局

我们可以每次\(dfs\)将要进入下一层时,我们都对下一层的棋盘和目标棋盘进行对比,如果差异值\(tot+step>maxstep\),那么我们就不进入下一层

详见代码

#include<bits/stdc++.h>
using namespace std;
const int nextx[8]={1,2,2,1,-1,-2,-2,-1};
const int nexty[8]={-2,-1,1,2,2,1,-1,-2};
//目标棋盘
int goal[7][7]={
    {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}
};
char ch[6][6];
int num[6][6];
bool flag=0;
int diff()//差异值
{
    int tot=0;
    for(int i=1;i<=5;i++)
    {
        for(int j=1;j<=5;j++)
        {
            if(num[i][j]!=goal[i][j])tot++;
        }
    }
    return tot;
}
bool check(int x,int y)
{
    return x>5||x<1||y>5||y<1;
}
void dfs(int step,int x,int y,int maxstep)
{
    if(flag)return ;
    if(step==maxstep)
    {
        if(!diff())flag=1;
        return ;
    }
    for(int i=0;i<8;i++)
    {
        int xx=x+nextx[i];
        int yy=y+nexty[i];
        if(check(xx,yy))continue;
        swap(num[x][y],num[xx][yy]);
        if(step+diff()<=maxstep)dfs(step+1,xx,yy,maxstep);
        swap(num[x][y],num[xx][yy]);
    }
}
int main()
{
    int t,stx,sty;
    scanf("%d",&t);
    while(t--)
    {
        flag=0;
        for(int i=1;i<=5;i++)
        {
            scanf("%s",ch[i]+1);
            for(int j=1;j<=5;j++)
            {
                if(ch[i][j]=='*')num[i][j]=2,stx=i,sty=j;   
                else num[i][j]=ch[i][j]-'0';
            }
        }
        for(int i=1;i<=15;i++)
        {
            dfs(0,stx,sty,i);
            if(flag)
            {
                printf("%d\n",i);
                break;
            }
        }
        if(!flag)puts("-1");
    }   
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ShuraEye/p/12110852.html