zoukankan      html  css  js  c++  java
  • 【bzoj1085】[SCOI2005]骑士精神

    【bzoj1085】[SCOI2005]骑士精神

    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*算法吧,省选的时候讲过课,估价函数是到达目标状态还有多少个不同,暴力计算,这样就可以了。
     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cmath>
     4 #include<iostream>
     5 #include<cstring>
     6 using namespace std;
     7 
     8 int k,flag;
     9 int ans[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}};
    10 const int lx[8]={1,1,-1,-1,2,2,-2,-2};
    11 const int ly[8]={2,-2,2,-2,1,-1,1,-1};
    12 
    13 bool judge(int a[5][5])//判断是否相等
    14 {
    15     for (int i=0;i<5;i++)
    16         for (int j=0;j<5;j++)
    17             if (ans[i][j]!=a[i][j]) return false;
    18     return true;        
    19 }
    20 bool eva(int a[5][5],int s)//计算估价函数
    21 {
    22     int v=0;
    23     for (int i=0;i<5;i++)
    24         for (int j=0;j<5;j++)
    25             if (a[i][j]!=ans[i][j]){v++;if(v+s>k)return false;}
    26     return true;        
    27 }
    28 void search(int s,int a[5][5],int x,int y)
    29 {
    30     //cout<<s<<" "<<x<<" "<<y<<endl;
    31     if (flag) return;
    32     if (s==k) {if (judge(a))flag=1;return;}
    33     for (int i=0;i<8;i++)
    34     {
    35         int nx=x+lx[i],ny=y+ly[i];
    36         if (nx<=4&&nx>=0&&ny>=0&&ny<=4)
    37         {
    38             swap(a[x][y],a[nx][ny]);
    39             if (eva(a,s)) 
    40             search(s+1,a,nx,ny);
    41             swap(a[x][y],a[nx][ny]);
    42         }
    43     }
    44 }
    45 int main()
    46 {
    47     int Cas;
    48     scanf("%d",&Cas);
    49     while(Cas--)
    50     {
    51         int a[5][5],x,y;char ch[10];
    52         memset(a,sizeof(a),0);
    53         for (int i=0;i<5;i++)
    54         {
    55             scanf("%s",ch);
    56             for (int j=0;j<5;j++)
    57                 if (ch[j]=='*') a[i][j]=2,x=i,y=j;
    58                 else a[i][j]=ch[j]-'0';
    59         }
    60         for (k=1;k<=15;k++)
    61         {
    62             search(0,a,x,y);
    63             if (flag) printf("%d
    ",k);
    64             if (flag) break;
    65         }
    66         if (!flag) printf("-1
    ");
    67         else flag=0;
    68     }
    69 }
  • 相关阅读:
    uva 10491 Cows and Cars
    uva 10910 Marks Distribution
    uva 11029 Leading and Trailing
    手算整数的平方根
    uva 10375 Choose and divide
    uva 10056 What is the Probability?
    uva 11027 Palindromic Permutation
    uva 10023 Square root
    Ural(Timus) 1081. Binary Lexicographic Sequence
    扩展欧几里得(求解线性方程)
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/7654392.html
Copyright © 2011-2022 走看看