• 洛谷 P2324 [SCOI2005]骑士精神 解题报告


    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
    ");return;}
        for(step=1;step<=15;step++)
        {
            dfs(0,ex,ey);
            if(flag)
            {
                printf("%d
    ",step);
                return;
            }
        }
        printf("-1
    ");
    }
    int main()
    {
        scanf("%d",&t);
        while(t--)
        {
            for(int i=1;i<=5;i++)
            {
                scanf("
    ");
                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

  • 相关阅读:
    Linux编程make命令(转)
    如何处理Global symbol * requires explicit package name编译错误,以及use strict用法
    6235与旧版本的区别
    Linux下动态链接库的使用
    MTK Socket学习——HTTP请求
    指针和指针的引用
    VC/MFC Combo Box控件的用法
    makefile教程
    常用数据类型使用转换详解
    Linux发送与接收信息
  • 原文地址:https://www.cnblogs.com/butterflydew/p/9409489.html
Copyright © 2020-2023  润新知