蓝桥杯2022年第十三届省赛真题-蜂巢 (模拟)

发布时间 2023-03-27 16:46:02作者: 谪仙梦

蜂巢由大量的六边形拼接而成,定义蜂巢中的方向为:0 表示正西方向,1 表示西偏北 60◦,2 表示东偏北 60◦,3 表示正东,4 表示东偏南 60◦,5 表示西偏南 60◦。 

对于给定的一点 O,我们以 O 为原点定义坐标系,如果一个点 A 由 O 点先向 d 方向走 p 步再向 (d + 2) mod 6 方向(d 的顺时针 120◦ 方向)走 q 步到达,则这个点的坐标定义为 (d, p, q)。在蜂窝中,一个点的坐标可能有多种。

下图给出了点 B(0, 5, 3) 和点 C(2, 3, 2) 的示意。

蓝桥杯2022年第十三届省赛真题蜂巢

给定点 (d1, p1, q1) 和点 (d2, p2, q2),请问他们之间最少走多少步可以到达?

输入格式

输入一行包含 6 个整数 d1, p1, q1, d2, p2, q2 表示两个点的坐标,相邻两个整数之间使用一个空格分隔。

输出格式

输出一行包含一个整数表示两点之间最少走多少步可以到达。 

样例输入

0 5 3 2 3 2

样例输出

7

提示

对于 25% 的评测用例,p1, p2 ≤ 103 ;
对于 50% 的评测用例,p1, p2 ≤ 105 ;
对于 75% 的评测用例,p1, p2 ≤ 107 ;
对于所有评测用例,0 ≤ d1, d2 ≤ 5,0 ≤ q1 < p1 ≤ 109,0 ≤ q2 < p2 ≤ 109 。
 
解答
 
  我们可以通过模拟算法解答此题
  1,先模拟出每个方向的移动对当前位置的变化
  
  public static double[] x = new double[]{-1,-0.5,0.5,1,0.5,-0.5};
    public static double[] y = new double[]{0,1,1,0,-1,-1};
  上面的数组中的数字与想象中移动带来的变化是一致的,第一个方向是向西一格,x移动-1,y不变,第二个方向西北,x移动-0.5,y移动1,以此类推
  
  2,算出移动之后两点的坐标,输入值d为方向,p和q为移动次数
  
double x1=0,y1=0,x2=0,y2=0;
            x1 = x[d1] * p1 + x[(d1+2)%6] * q1;
            y1 = y[d1] * p1 + y[(d1+2)%6] * q1;

            x2 = x[d2] * p2 + x[(d2+2)%6] * q2;
            y2 = y[d2] * p2 + y[(d2+2)%6] * q2;

  点1的x和y轴都会根据方向进行移动,取出对应方向会对x和y轴的距离变化再乘移动次数,就是移动后的坐标点,再计算最后两点的距离;

 

  3,由于每次y的变化都为一,所以y值直接决定移动次数,在每次以y移动的x只增加0.5格的基础上,如果x的距离*2(y/2的距离)超过了y的移动次数则应该左右移动达到目标点,

  因为y轴相等了,只需要移动x轴,所以就是每次移动一格,所以在y的间距的基础上加上x*2 - y(x - y/2)即可

  

double xLoc = Math.abs(x2-x1);
            double yLoc = Math.abs(y2-y1);

            int res = (int) yLoc;
            if(xLoc - yLoc/2 > 0) {
                res += (int)Math.abs(xLoc - yLoc/2);
            }