• ACM Curling 2.0


    在行星MM-21上,今年奥运会之后,冰壶(curling)越来越受欢迎。  但规则与我们有所不同。 该游戏是在冰盘上进行的,在冰棋盘上标有方形网格。他们只用一块石头。 游戏的目的是以最少的动作( the minimum number of moves.)让石头从开始到目标位置。

    Fig. 1 是游戏板的示例。 一些方块可能被石块占据。  有两个特殊的方格即开始和目标,没有被块占据。 (这两个方块是不同的。)这两个方块是不同的。)一旦石头开始移动,它将继续进行,直到它撞到一个石块。为了把石头带到目标位置,你可能必须通过击中石块来阻止石块,并重新抛出。


    Fig. 1: Example of board (S: start, G: goal)

    石头的运动遵从以下规则:

    • 一开始,石头会在起始方块。
    • 石头的运动限于x和y方向。 对角线移动是禁止的。
    • 当石头静止时,你可以通过扔它移动。 除非立即被阻止,否则您可以将其扔到任何方向(图2(a))。
    • 一旦投掷,石头会继续向同一方向移动,直到发生以下情况之一:
      • 石头撞上一块(图2(b),(c))。
      • 石头停在撞击它的石块的旁边的正方形上。.
        • 石块消失
      • 石块从木板上掉出来
        • 游戏结束
      • 石头到达目标位置
        • 石头停在那里,游戏结束了。
    • 你不能在比赛中扔石头10次以上。 如果石头在10次移动中没有达到目标,游戏就会失败。


    Fig. 2: Stone movements

    根据规则(under the rules),我们想知道一开始的石头是否可以达到目标,如果是,则需要最少的移动次数。

    在图1所示的初始配置中,需要4次移动才能将石头从开始位置移动到目标位置。 路线如图3(a)所示。 注意当石头到达目标时,游戏板配置如图3(b)所示。


    Fig. 3: The solution for Fig. D-1 and the final board configuration

    Input

    输入是一系列数据集。 输入的结尾由包含由空格分隔的两个零的行指示。 数据集的数量从不超过100。

    每个数据集格式如下。

    the width(=w) and the height(=h) of the board 
    First row of the board 
    ... 
    h-th row of the board

    板的宽度和高度满足:2 < = w < = 20,1 < = h < = 20。

    每一行都由一个空格分隔的w十进制数组成。这个数字描述了相应的正方形的状态。

    0 vacant square
    1 block
    2 start position
    3 goal position

    The dataset for Fig. D-1 is as follows:

    6 6 
    1 0 0 2 1 0 
    1 1 0 0 0 0 
    0 0 0 0 0 3 
    0 0 0 0 0 0 
    1 0 0 0 0 1 
    0 1 1 1 1 1

    Output

    对于每个数据集,打印一行有一个十进制整数,表示从开始到目标的路线的最小移动数。如果没有这样的路由,则输出- 1。每行不应该有除这个数字以外的任何字符。

    Sample Input

    2 1
    3 2
    6 6
    1 0 0 2 1 0
    1 1 0 0 0 0
    0 0 0 0 0 3
    0 0 0 0 0 0
    1 0 0 0 0 1
    0 1 1 1 1 1
    6 1
    1 1 2 1 1 3
    6 1
    1 0 2 1 1 3
    12 1
    2 0 1 1 1 1 1 1 1 1 1 3
    13 1
    2 0 1 1 1 1 1 1 1 1 1 1 3
    0 0

    Sample Output

    1
    4
    -1
    4
    10
    -1

     1 #include<iostream>
     2 #include<cstdio> 
     3 using namespace std;
     4 const int MAX_N = 25;
     5 const int INF = 1<<30;
     6 int board[MAX_N][MAX_N];
     7 /*四个方向*/
     8 int dx[] = {1,-1,0,0};
     9 int dy[] = {0,0,1,-1};
    10 int w,h,bx,by,ex,ey,mintimes;
    11 void solve(int row ,int col,int count)
    12 {
    13     if(count == 10 && board[row][col] != 3)  //移动次数超10次并且没有到达终点 
    14         return ;
    15     else if(board[row][col] == 3)  //到达终点位置 
    16     {
    17         mintimes = min(mintimes,count);  //找最小的移动次数
    18         return; 
    19     }
    20     for(int i = 0; i < 4; i++)
    21     {
    22         int ny = row + dy[i];
    23         int nx = col + dx[i];
    24         if(nx >= 0 && ny >= 0 && nx < w && ny < h)  //确定冰壶在网格内 
    25         {
    26             if(board[ny][nx] == 1) continue;  //遇到石块
    27             while(nx >= 0 && ny >= 0 && nx < w && ny < h && board[ny][nx] != 1 &&board[ny][nx] != 3)
    28             {
    29                 ny += dy[i];
    30                 nx += dx[i];    
    31             } 
    32             if(nx < 0 || nx >= w || ny < 0|| ny >= h) continue; //飞出冰盘 
    33             int temp = board[ny][nx];
    34             int x = nx,y = ny;
    35             if(board[ny][nx] == 1)
    36             {
    37                 board[ny][nx] = 0;
    38                 ny -= dy[i];
    39                 nx -= dx[i];
    40             }
    41             solve(ny,nx,count+1);
    42             board[y][x] = temp;  //回复原来状态
    43             
    44         }
    45     }
    46 }
    47 int main()
    48 {
    49     while(cin>>w>>h,w||h)
    50     {
    51         for(int i =0; i < h;i++)
    52             for(int j = 0; j < w;j++)
    53             {
    54                 scanf("%d",&board[i][j]);
    55                 /*标记开始位置和结束位置*/
    56                 if(board[i][j] == 2)
    57                 {
    58                     bx = j;
    59                     by = i;
    60                  }else if(board[i][j] == 3){
    61                       ex = j;
    62                       ey = i;
    63                 }
    64             }
    65         mintimes = INF;
    66         solve(by,bx,0);
    67         if(mintimes == INF)
    68             cout<<"-1"<<endl;
    69         else
    70             cout<<mintimes<<endl;
    71                 
    72     } 
    73     return 0;
    74 }
  • 相关阅读:
    python 去除字符串两端字符串
    python 找到列表中满足某些条件的元素
    python join函数
    Ambiguous mapping. Cannot map "***Controller" been method解决办法
    uflo2安装与配置
    uflo2概述
    Mybatis-plus中的常用注解
    Spring Cloud Eureka配置文件详解 (还没细看)
    idea安装lombok
    PowerDesigner最基础的使用方法入门学习(一)
  • 原文地址:https://www.cnblogs.com/jj81/p/7449000.html
Copyright © 2020-2023  润新知