1. 程式人生 > >洛谷 P2324 [SCOI2005]騎士精神 解題報告

洛谷 P2324 [SCOI2005]騎士精神 解題報告

else if urn swa swap 報告 while 就是 include har

P2324 [SCOI2005]騎士精神

題目描述

技術分享圖片

輸入輸出格式

輸入格式:

第一行有一個正整數T(T<=10),表示一共有N組數據。接下來有T個5×5的矩陣,0表示白色騎士,1表示黑色騎士,*表示空位。兩組數據之間沒有空行。

輸出格式:

對於每組數據都輸出一行。如果能在15步以內(包括15步)到達目標狀態,則輸出步數,否則輸出-1。


一看到15,莫名的想到叠代加深。

然後發現這個玩意12都跑不過去。想過估價函數,但感覺操作次數會很多就放棄了。

實際上這個題的重點就是估價函數

設估價函數為與目標狀態不同的點的個數+1(這個+1是為了最後一步空白的)

然後跑IDA* 就行了(事實是A*更快)


Code:

#include <cstdio>
const int N=6;
int t,sta[N][N],step,ex,ey,flag;
int to[N][N]=
{
{0,0,0,0,0,0},
{0,1,1,1,1,1},
{0,-1,1,1,1,1},
{0,-1,-1,0,1,1},
{0,-1,-1,-1,-1,1},
{0,-1,-1,-1,-1,-1},
};
inline int estimate()
{
    int res=0;
    for(int i=1;i<=5;i++)
        for(int j=1;j<=5;j++)
            if(to[i][j]!=sta[i][j])
                res++;
    return res;
}
int dx[9]={0,-2,-1,1,2,2,1,-1,-2};
int dy[9]={0,1,2,2,1,-1,-2,-2,-1};
inline void Swap(int &x,int &y)
{
    int tmp=x;
    x=y;
    y=tmp;
}
void dfs(int dep,int x,int y)
{
    if(flag) return;
    if(estimate()+dep>step+1) return;
    if(step==dep){flag=1;return;}
    for(int i=1;!flag&&i<=8;i++)
    {
        int X=x+dx[i],Y=y+dy[i];
        if(X>0&&Y>0&&X<=5&&Y<=5)
        {
            Swap(sta[x][y],sta[X][Y]);
            dfs(dep+1,X,Y);
            Swap(sta[x][y],sta[X][Y]);
        }
    }
}
void work()
{
    flag=0;
    if(estimate()==0) {printf("0\n");return;}
    for(step=1;step<=15;step++)
    {
        dfs(0,ex,ey);
        if(flag)
        {
            printf("%d\n",step);
            return;
        }
    }
    printf("-1\n");
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        for(int i=1;i<=5;i++)
        {
            scanf("\n");
            for(int j=1;j<=5;j++)
            {
                char c;
                scanf("%c",&c);
                if(c==‘*‘) ex=i,ey=j,sta[i][j]=0;
                else if(c==‘1‘) sta[i][j]=1;
                else sta[i][j]=-1;
            }
        }
        work();
    }
    return 0;
}

2018.8.2

洛谷 P2324 [SCOI2005]騎士精神 解題報告