zoukankan      html  css  js  c++  java
  • 1085: [SCOI2005]骑士精神

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 3371  Solved: 1990
    [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
     
    第一次写启发式搜索
    直接dfs爆搜会TLE,于是就要用到神奇的A-star(简称A*)算法
     
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 using namespace std;
     5 
     6 const char mat[5][5]={'1','1','1','1','1',
     7                      '0','1','1','1','1',
     8                      '0','0','*','1','1',
     9                      '0','0','0','0','1',
    10                      '0','0','0','0','0'};
    11 
    12 int T,x,y,k;
    13 int mx[8]={-2,-1,1,2,2,1,-1,-2};
    14 int my[8]={1,2,2,1,-1,-2,-2,-1};
    15 char mp[10][10];
    16 bool flag;
    17 
    18 void read()
    19 {
    20     flag=0;
    21     for(int i=0;i<5;i++)
    22         scanf("%s",mp[i]);
    23     for(int i=0;i<5;i++)
    24         for(int j=0;j<5;j++)
    25             if(mp[i][j]=='*') x=i,y=j;
    26 }
    27 
    28 bool check()
    29 {
    30     for(int i=0;i<5;i++)
    31         for(int j=0;j<5;j++)
    32             if(mp[i][j]!=mat[i][j]) return false;
    33     return true;
    34 }
    35 
    36 bool judge(int now)
    37 {
    38     int val=0;
    39     for(int i=0;i<5;i++)
    40         for(int j=0;j<5;j++)
    41             if(mp[i][j]!=mat[i][j])
    42             {
    43                 val++;
    44                 if(val+now>k) return false;
    45             }
    46     return true;
    47 }
    48 
    49 void dfs(int now,int x,int y)
    50 {
    51     if(now>=k)
    52     {
    53         if(check()) flag=1;
    54         return;
    55     }
    56     if(flag) return;
    57     for(int i=0;i<8;i++)
    58     {
    59         int nx=x+mx[i],ny=y+my[i];
    60         if(nx<0||nx>4||ny<0||ny>4) continue;
    61         swap(mp[x][y],mp[nx][ny]);
    62         if(judge(now)) dfs(now+1,nx,ny);
    63         swap(mp[x][y],mp[nx][ny]);
    64     }
    65 }
    66 
    67 int main()
    68 {
    69     scanf("%d",&T);
    70     while(T--)
    71     {
    72         read();
    73         for(k=1;k<=15;k++)
    74         {
    75             dfs(0,x,y);
    76             if(flag)
    77             {
    78                 printf("%d
    ",k);
    79                 break;
    80             }
    81         }
    82         if(!flag) printf("-1
    ");
    83     }
    84     return 0;
    85 }
  • 相关阅读:
    功能:Java注解的介绍和反射使用
    功能:@Vaild注解使用及扩展
    转载:微信小程序view布局
    功能:Java8新特性steam流
    功能:Linux运行jar包Shell脚本
    转载:Windows使用tail -f 监控文件
    转载:java.math.BigDecimal 比较大小
    问题:跨域及解决方案
    基于 @SelectProvider 注解实现无侵入的通用Dao
    SpringBoot中的异步操作与线程池
  • 原文地址:https://www.cnblogs.com/InWILL/p/9457530.html
Copyright © 2011-2022 走看看