zoukankan      html  css  js  c++  java
  • codeforces A. Rook, Bishop and King 解题报告

    题目链接:http://codeforces.com/problemset/problem/370/A

    题目意思:根据rook(每次可以移动垂直或水平的任意步数(>=1)),bishop(每次可以移动对角线上的任意步数(>=1))和king(每次垂直、水平或对角线的一步(=1))的走法,给出起始位置和结束位置。求出这三种棋子分别从起始位置走到最终位置的最少步数。

     

               rook           bishop          king

      

      首先,先解释下面所说的直线和斜线。

      直线:是坐标轴上与x轴平行或与y轴平行的情况的直线。

          斜线:图中bishop能走的斜线(能走到坐标点的格子),不是一般的那种斜线(可能走的过程中走不到整数的格子的)

          rook是最容易的,如果起始位置和最终位置在同一直线,那么只需要一步即可,否则是两步。

          比较麻烦的是bishop,一开始很天真地以为,如果不是斜线的那种情况,bishop就无法到达最终位置。其实处于同一直线也是可以的。如果是(3,1)到(5,1),可以通过(4,2)这个桥梁,到达终点。还有,一般斜线的情况,例如(3,1)到(4,6),可以经过(6,4)。

          还是以(3,1)到(4,6)这个例子来说明我的解决办法

         

            考虑到棋盘的特殊性,分别以起点和终点画一条斜线(假设对应为k1和k2),两条斜线必须满足斜率是不同的,满足k1 * k2 = -1),求出两条斜线的交点,判断是否为整数。(注意,即使这个交点超出棋盘范围之外也没有所谓,因为它可以通过另外一个对称点(以黄色标记)来到达目的地)。可能大家会觉得求出交点很麻烦,但是其实也不是很难。由于已经知道斜线上的斜率和交点,那么方程就确定了)

           K1 = -1, 方程为: y = -x + 4 (y1 = k1*x1 + b1) 

       K2 = 1,   方程为: y = x + 2   (y2 = k2*x2 + b2)

          联立方程 y = (4 + 2)/ 2 = 2

          求出的y是整数,说明交点在格子上,其实得出的交点是什么不重要,关键是判断是否为整数,是则bishop的步数为2,否则不可达,为0。抽象出来,b1 = x1 + y1,b2 = y2 - x2,交点y = (b1+b2)/2。

           至此,bishop解决了,还有最后的king,这里不详细说明,不过本人觉得也是要考虑清楚的。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <algorithm>
     5 #include <cmath>
     6 
     7 int main()
     8 {
     9     int r1, c1, r2, c2, t1, t2, flag1, flag2;
    10     while (scanf("%d%d%d%d", &r1, &c1, &r2, &c2) != EOF)
    11     {
    12         // rook
    13         flag2 = 0;
    14         if ((r1 == r2 && c1 != c2) || (c1 == c2 && r1 != r2))
    15         {
    16             flag2 = 1;
    17             printf("1 ");
    18         }
    19         else
    20             printf("2 ");
    21         // bishop
    22         flag1 = 0;
    23         if (abs(r1-r2) == abs(c1-c2))
    24         {
    25             printf("1 "); 
    26             flag1 = 1;
    27         }
    28         else
    29         {
    30             t1 = r1 + c1;
    31             if (r2 > c2)
    32                 t2 = r2 - c2;
    33             else
    34                 t2 = c2 - r2;
    35             if ((t1 + t2) % 2 == 0)
    36                 printf("2 ");
    37             else
    38                 printf("0 ");
    39         }
    40         // king
    41         if (flag2) //一条直线
    42             printf("%d
    ", abs(r1-r2) + abs(c1-c2));
    43         else if (flag1) //一条斜线
    44             printf("%d
    ", abs(r1-r2));
    45         else if (abs(r1-r2) < abs(c1-c2))
    46             printf("%d
    ", abs(c1-c2));
    47         else
    48             printf("%d
    ", abs(r1-r2));
    49     }
    50     return 0;
    51 } 
  • 相关阅读:
    Python之旅.第十章.mysql..
    Python之旅.第十章.mysql.
    Python之旅.第十章.mysql.
    Python之旅.第十章.mysql。
    Mac 移动光标和删除
    网络编程——socket开发
    闭包(closure)
    命名空间 and 作用域
    Function
    for循环的禁忌
  • 原文地址:https://www.cnblogs.com/windysai/p/3474244.html
Copyright © 2011-2022 走看看