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

    1085: [SCOI2005]骑士精神

    Time Limit: 10 Sec  Memory Limit: 162 MB

    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
     
    一道练习 IDA* 的好题
    套一层循环表示最大步数限制,估价函数为所有不在位置的节点个数 -1
    因为估价步数是最小步数,所以如果当前的步数 + 估价步数 > lim , 就可以return
    跑到飞快。
     
     
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <cmath>
      6 #define LL long long
      7 
      8 using namespace std;
      9 
     10 int T;
     11 int lim = 0;
     12 int flag = 0;
     13 char map[10][10];
     14 char rt[10][10];
     15 char status[10][10];
     16 int move[10][2];
     17 
     18 void init()
     19 {
     20     move[1][0] = 1, move[1][1] = 2;
     21     move[2][0] = -1, move[2][1] = 2;
     22     move[3][0] = 1, move[3][1] = -2;
     23     move[4][0] = -1, move[4][1] = -2;
     24     move[5][0] = 2, move[5][1] = 1;
     25     move[6][0] = -2, move[6][1] = 1;
     26     move[7][0] = -2, move[7][1] = -1;
     27     move[8][0] = 2, move[8][1] = -1;
     28 }
     29 
     30 inline LL read()
     31 {
     32     LL x = 0, w = 1; char ch = 0;
     33     while(ch < '0' || ch > '9') {
     34         if(ch == '-') {
     35             w = -1;
     36         }
     37         ch = getchar();
     38     }
     39     while(ch >= '0' && ch <= '9') {
     40         x = x * 10 + ch - '0';
     41         ch = getchar();
     42     }
     43     return x * w;
     44 }
     45 int judge()
     46 {
     47     int sum = 0;
     48     for(int i = 1; i <= 5; i++) {
     49         for(int j = 1; j <= 5; j++) {
     50             if(status[i][j] != rt[i][j]) {
     51                 sum++;
     52             }
     53         }
     54     }
     55     return sum;
     56 }
     57 
     58 void DFS(int x, int y, int step)
     59 {
     60     if(flag) {
     61         return;
     62     }
     63     int astar = judge();
     64     if(astar == 0) {
     65         flag = 1;
     66         return;
     67     }
     68     astar--;
     69     if(step + astar > lim) {
     70         return;
     71     }
     72     for(int i = 1; i <= 8; i++) {
     73         int xx = x + move[i][0], yy = y + move[i][1];
     74         char last;
     75         if(xx >= 1 && xx <= 5 && yy >= 1 && yy <= 5) {
     76             last = status[xx][yy];
     77             status[xx][yy] = '*';
     78             status[x][y] = last;
     79             DFS(xx, yy, step + 1);
     80             status[xx][yy] = last;
     81             status[x][y] = '*';
     82         }
     83     }
     84 }
     85 
     86 int main()
     87 {
     88     init();
     89     for(int i = 1; i <= 5; i++) {
     90         for(int j = 1; j <= 5; j++) {
     91             rt[i][j] = '0';
     92         }
     93     }
     94     for(int i = 1; i <= 2; i++) {
     95         for(int j = i; j <= 5; j++) {
     96             rt[i][j] = '1';
     97         }
     98     }
     99     for(int i = 3; i <= 4; i++) {
    100         for(int j = i + 1; j <= 5; j++) {
    101             rt[i][j] = '1';
    102         }
    103     }
    104     rt[3][3] = '*';
    105     T = read();
    106     while(T--) {
    107         flag = 0;
    108         int x, y;
    109         for(int i = 1; i <= 5; i++) {
    110             scanf("%s", map[i] + 1);
    111             for(int j = 1; j <= 5; j++) {
    112                 if(map[i][j] == '*') {
    113                     x = i, y = j;
    114                 }
    115             }
    116         }
    117         for(lim = 0; lim <= 15; lim++) {
    118             for(int i = 1; i <= 5; i++) {
    119                 for(int j = 1; j <= 5; j++) {
    120                     status[i][j] = map[i][j];
    121                 }
    122             }
    123             DFS(x, y, 0); 
    124             if(flag) {
    125                 printf("%d
    ", lim);
    126                 break;
    127             }
    128         }
    129         if(!flag) {
    130             printf("-1
    ");
    131         }
    132     }
    133 }
    134 
    135 
    136 /*
    137 2
    138 
    139 10110
    140 
    141 01*11
    142 
    143 10111
    144 
    145 01001
    146 
    147 00000
    148 
    149 01011
    150 
    151 110*1
    152 
    153 01110
    154 
    155 01010
    156 
    157 00100
    158 */
    View Code
  • 相关阅读:
    linux下安装vsftp
    CentOS 7.0编译安装Nginx1.6.0+MySQL5.6.19+PHP5.5.14
    Centos编译安装PHP 5.5笔记
    centos使用更新更快的yum源
    使用Android Studio搭建Android集成开发环境
    设计模式(三)原型模式
    overridePendingTransition
    Android手势密码实现
    UserInfoActivity用户图像修改和退出登录
    设计模式(二)建造者模式
  • 原文地址:https://www.cnblogs.com/wuenze/p/8626584.html
Copyright © 2011-2022 走看看