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

    题目描述

    输入输出格式

    输入格式:

    第一行有一个正整数T(T<=10),表示一共有N组数据。接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑士,*表示空位。两组数据之间没有空行。

    输出格式:

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

    输入输出样例

    输入样例#1: 复制
    2
    10110
    01*11
    10111
    01001
    00000
    01011
    110*1
    01110
    01010
    00100
    
    输出样例#1: 复制
    7
    -1
    

    说明

    迭代次数dep

    A*算法是利用估价函数h()进行剪枝

    h()大于实际值就会错误

    h()小于实际值太多效率会底下

    所以h要慎重考虑

    此题h可以这么计算:

    当前棋盘有cnt个与目标棋盘不同的棋子

    如果cnt等于0,那么退出

    如果cnt不等于0,那么说明至少要走cnt-1步

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 using namespace std;
     7 char ch[10][10];
     8 int s[5][5];
     9 const int ss[5][5]=
    10   {{1,1,1,1,1},
    11    {0,1,1,1,1},
    12    {0,0,2,1,1},
    13    {0,0,0,0,1},
    14    {0,0,0,0,0}};
    15 int sx,sy,deeeep,flag;
    16 const int dx[8]={2,-2,1,-1,2,-2,1,-1},dy[8]={1,1,2,2,-1,-1,-2,-2};
    17 int h()
    18 {int i,j;
    19   int cnt=0;
    20   for (i=0;i<=4;i++)
    21     {
    22       for (j=0;j<=4;j++)
    23     {
    24       if (s[i][j]!=ss[i][j]) cnt++;
    25     }
    26     }
    27   return cnt;
    28 }
    29 void dfs(int x,int y,int sum,int dep)
    30 {int i;
    31   if (flag) return;
    32   int H=h();
    33   if (!H)
    34     {
    35       flag=1;
    36       return;
    37     }
    38   if (sum+H-1>dep) return;
    39   int xx,yy;
    40   for (i=0;i<8;i++)
    41     {
    42       xx=x+dx[i],yy=y+dy[i];
    43       if (xx<0||yy<0||xx>=5||yy>=5) continue;
    44       swap(s[x][y],s[xx][yy]);
    45       dfs(xx,yy,sum+1,dep);
    46       swap(s[x][y],s[xx][yy]);
    47     }
    48 }
    49 int main()
    50 {int T,i,j;
    51   cin>>T;
    52   while (T--)
    53     {
    54       for (i=0;i<=4;i++)
    55     {
    56       scanf("%s",ch[i]);
    57       for (j=0;j<=4;j++)
    58         if (ch[i][j]=='*') sx=i,sy=j,s[i][j]=2;
    59         else s[i][j]=ch[i][j]-'0';
    60     }
    61       deeeep=0;
    62       flag=0;
    63       while (deeeep<=15)
    64     {
    65       dfs(sx,sy,0,deeeep);
    66       if (flag) break;
    67       deeeep++;
    68     }
    69       if (flag==0) printf("-1
    ");
    70       else printf("%d
    ",deeeep);
    71     }
    72 }
  • 相关阅读:
    求全排列,调用C++函数
    ZOJ 3508 (the war)
    HDU 1285
    SDUT--枚举(删数问题)
    SDUT--进制转换
    位运算
    [NOI2015]软件包管理器
    列队[noip2017]
    [APIO2007]动物园
    [NOI2001]炮兵阵地
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8525598.html
Copyright © 2011-2022 走看看