1. 题目:
蜂巢由大量的六边形拼接而成,定义蜂巢中的方向为:0 表示正西方向,1 表示西偏北 60°,2 表示东偏北 60°,3 表示正东,4 表示东偏南60°,5 表示西 偏南 60°
对于给定的一点 O,我们以 ◎ 为原点定义坐标系,如果一个点 A 由 O点 先向 d方向走 p步再向(d+ 2)mod 6 方向(d 的顺时针 120°方向) 走 q 步到 达,则这个点的坐标定义为(a,p,q)。在蜂窝中,一个点的坐标可能有多种。
下图给出了点 B(0,5,3)和点 C(2,3,2)的示意。
给定点(d1,p1,q1)和点(d2,p2,q2),请问他们之间最少走多少步可以到达?
输入格式
输入一行包含6个整数 d1,p1,q1,d2,p2,q2 表示两个点的坐标,相邻两个整 数之间使用一个空格分隔。
输出格式
输出一行包含一个整数表示两点之间最少走多少步可以到达。
样例输入
0 5 3 2 3 2
样例输出
7
2. 我的代码:
import os import sys # 请在此输入您的代码 d1, p1, q1, d2, p2, q2 = map(int, input().split(" ")) # 起始方向 与 位移坐标 映射 relation = [[-1, 0], [-1, 1], [0, 1], [1, 0], [1, -1], [0, -1]] # 计算变换坐标系后的坐标 x1 = y1 = x2 = y2 = 0 x1 += relation[d1][0] * p1 y1 += relation[d1][1] * p1 x1 += relation[(d1 + 2) % 6][0] * q1 y1 += relation[(d1 + 2) % 6][1] * q1 x2 += relation[d2][0] * p2 y2 += relation[d2][1] * p2 x2 += relation[(d2 + 2) % 6][0] * q2 y2 += relation[(d2 + 2) % 6][1] * q2 # 计算坐标差值 det_x = x1 - x2 det_y = y1 - y2 # 排除非曼哈顿距离的情况 if det_x * det_y < 0: print(max(abs(det_x), abs(det_y))) else: print(abs(det_x) + abs(det_y))
建立一个x、y轴夹角为60度:
由于6前进方向,表示为新的坐标系下的坐标。相对应的,正对于不同前进方向,建立的新变换规则如下(表示朝着i方向移动一次,对应的x移动和y移动):
relation = [[-1, 0], [-1, 1], [0, 1], [1, 0], [1, -1], [0, -1]]
然后,对输入的三维移动坐标进行变换,得到两个点分别的最终落脚点(每个点都是先向前移动一遍,然后再右转120°移动一遍):
x1 += relation[d1][0] * p1 y1 += relation[d1][1] * p1 x1 += relation[(d1 + 2) % 6][0] * q1 y1 += relation[(d1 + 2) % 6][1] * q1 x2 += relation[d2][0] * p2 y2 += relation[d2][1] * p2 x2 += relation[(d2 + 2) % 6][0] * q2 y2 += relation[(d2 + 2) % 6][1] * q2
然后,通过计算坐标差值,如果两个坐标关系为一个左上、一个右下,则最短距离不是曼哈顿距离,而是需要减去等边三角形的一条边,例如:
其距离为:
if det_x * det_y < 0: print(max(abs(det_x), abs(det_y)))
其余情况就是曼哈顿距离,即x差值的绝对值加上y差值的绝对值