zoukankan      html  css  js  c++  java
  • 【BZOJ1085】【SCOI2005】骑士精神 [A*搜索]

    骑士精神

    Time Limit: 10 Sec  Memory Limit: 162 MB
    [Submit][Status][Discuss]

    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

    HINT

      Ans<=15

    Solution

      看到这题,我们没有什么思路,只能运用搜索,然后把错位的个数当做估价,跑一遍A*就可以了。

    Code

    #include<iostream>  
    #include<string>  
    #include<algorithm>  
    #include<cstdio>  
    #include<cstring>  
    #include<cstdlib>  
    #include<cmath>
    using namespace std;
    typedef long long s64;
    
    const int ONE = 1001;
    
    int T;
    int a[8][8],Step,Vx,Vy;
    char ch[8];
    bool PD;
    int dx[]={1,2,-1,-2,1,2,-1,-2};
    int dy[]={2,1,2,1,-2,-1,-2,-1};
    int Goal[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 int get()
    {
            int res=1,Q=1;  char c;
            while( (c=getchar())<48 || c>57)
            if(c=='-')Q=-1;
            if(Q) res=c-48; 
            while((c=getchar())>=48 && c<=57) 
            res=res*10+c-48;
            return res*Q; 
    }
    
    int Evaluation()
    {
            int res = 0;
            for(int i=1;i<=5;i++)
            for(int j=1;j<=5;j++)
                if(a[i][j] != Goal[i][j])
                res++;
            return res;
    }
    
    void Dfs(int T,int x,int y)
    {
            if(PD) return;
            if(T == Step)
            {
                PD = !Evaluation();
                return;
            }
            
            for(int i=0;i<8;i++)
            {
                int Nx = x+dx[i], Ny = y+dy[i];
                if(!(1<=Nx && Nx<=5 && 1<=Ny && Ny<=5)) continue;
                swap(a[x][y], a[Nx][Ny]);
                if(Evaluation() + T <= Step) Dfs(T+1, Nx,Ny);
                swap(a[x][y], a[Nx][Ny]);
            }
    }
    
    void Solve()
    {
            for(int i=1;i<=5;i++)
            {
                scanf("%s",ch+1);
                for(int j=1;j<=5;j++)
                {
                    if(ch[j] == '*') {a[i][j] = 2, Vx=i,Vy=j;}
                    else a[i][j] = ch[j]-'0';
                }
            }
            
            PD=0;
            for(Step=1;Step<=15;Step++)
            {
                Dfs(0,Vx,Vy);
                if(PD) break;
            }
            
            printf("%d
    ",PD==1 ? Step:-1);
    }
    
    int main()
    {
            T=get();
            while(T--)
                Solve();
    }
    View Code
  • 相关阅读:
    PHP金课-第三章 PHP数组和字符串
    PHP金课-第二章 PHP流程控制语句
    PHP金课-第一章 PHP起点
    PHP金课-课程大纲、燃尽图
    客车网上订票系统项目--购票支付、个人中心我的订单
    centos7安装phpstudy
    php 安装redis扩展
    php+sqlserver处理读取decimal 类型数据,不满1的数字会去掉0的问题
    PHP icov转码报错解决方法,iconv(): Detected an illegal character in input string
    thinkphp5 部署到iis服务器url重写
  • 原文地址:https://www.cnblogs.com/BearChild/p/6828936.html
Copyright © 2011-2022 走看看