• [luogu 2324][SCOI 2005] 骑士精神 (A*算法)


    Description
    在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位。在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2,纵坐标相差为1的格子)移动到空位上。 给定一个初始的棋盘,怎样才能经过移动变成如下目标棋盘: 为了体现出骑士精神,他们必须以最少的步数完成任务。
    这里写图片描述
    Input
    第一行有一个正整数T(T<=10),表示一共有N组数据。接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑士,*表示空位。两组数据之间没有空行。

    Output
    对于每组数据都输出一行。如果能在15步以内(包括15步)到达目标状态,则输出步数,否则输出-1。

    Sample Input
    2
    10110
    01*11
    10111
    01001
    00000
    01011
    110*1
    01110
    01010
    00100
    Sample Output
    7
    -1

    A*:
    s为当前深度,u为与目标不一样的数量,枚举ans,如果s+u>ans就不用搜了

    code:

    //By Menteur_Hxy
    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #define f(i,a,b) for(register int i=(a);i<=(b);i++)
    using namespace std;
    
    int T,k,x,y,flag=0;
    int da[5][5];
    int aim[5][5]={
        {1,1,1,1,1},
        {0,1,1,1,1},
        {0,0,2,1,1},
        {0,0,0,0,1},
        {0,0,0,0,0}
    };
    int xx[8]={1,1,-1,-1,2,2,-2,-2};
    int yy[8]={2,-2,2,-2,1,-1,1,-1};
    
    
    bool jud(int a[5][5]) {
        f(i,0,4) f(j,0,4) 
            if(a[i][j]!=aim[i][j]) return 0;
        return 1;
    }
    
    bool eva(int a[5][5],int s) {
        int u=0;
        f(i,0,4) f(j,0,4) 
            if(a[i][j]!=aim[i][j]) 
                if((++u)+s>k) return 0;
        return 1;
    }
    
    void serch(int s,int a[5][5],int x,int y) {
        if(s==k) {if(jud(a)) flag=1; return ;}
        if(flag) return ;
        f(i,0,8) {
            int nx=x+xx[i],ny=y+yy[i];
            if(nx<0 || nx>4 || ny<0 || ny>4) continue;
            swap(a[x][y],a[nx][ny]);
            if(eva(a,s)) serch(s+1,a,nx,ny);
            swap(a[x][y],a[nx][ny]);
        }
    }
    
    int main() {
        scanf("%d",&T);
        while(T--) {
            memset(da,0,sizeof da);
            f(i,0,4) {  
                char ch[10]; scanf("%s",ch);
                f(j,0,4) 
                    if(ch[j]=='*') da[i][j]=2,x=i,y=j;
                    else da[i][j]=ch[j]-'0';
            }
            for(k=1;k<=15;k++) 
                {serch(0,da,x,y); if(flag) {printf("%d
    ",k);break;}}
            if(!flag) printf("-1
    ");
            else flag=0;
        }
        return 0;
    }
    版权声明:本文为博主原创文章,未经博主允许不得转载。 博主:https://www.cnblogs.com/Menteur-Hxy/
  • 相关阅读:
    滚轮事件的防冒泡、阻止默认行为的代码(效果是:只让当前div滚动,连当前文档都不滚动的效果)
    js原生封装getClassName()方法-ie不支持getElementsByClassName,所以要自己实现获取类名为className的所有元素
    使用 RequireJS 优化 Web 应用前端
    javascript的页面加载及性能优化(兼容IE7)
    JavaScript中的this陷阱的最全收集--没有之一
    mysql 配置MHA
    mysql 在linux下的完整安装过程
    vue 开发系列(八) 动态表单开发
    vue 开发系列(七) 路由配置
    vue 开发系列(六) 企业微信整合
  • 原文地址:https://www.cnblogs.com/Menteur-Hxy/p/9247973.html
Copyright © 2020-2023  润新知