import math n, h = map(int, input().split()) for _ in range(n): x, y, z = map(int, input().split()) z_mirror = 2 * h - z g = math.gcd(math.gcd(abs(x), abs(y)), abs(z_mirror)) i = x // g j = y // g k = z_mirror // g print(i, j, k)
几何分析
我们需要找到一个方向向量 (i, j, k),使得从原点 (0, 0, 0) 出发的激光经过水面 z = h 的反射后到达目标点 (x_i, y_i, z_i)。
反射的几何方法
在几何光学中,反射可以等效为“镜像法”。即,对于反射面 z = h,可以构造目标点关于水面的镜像点 (x_i, y_i, 2h - z_i)。然后,激光的方向就是从原点 (0, 0, 0) 指向镜像点 (x_i, y_i, h + h - z_i) 的方向。
这是因为:
- 实际反射路径可以看作是激光直接穿过水面到达镜像点,但由于反射,实际路径是到达水面后反射到目标点。
- 因此,方向向量可以是从原点到镜像点的方向。
方向向量的计算
镜像点的坐标为 (x_i, y_i, h + h - z_i)。因此,从原点 (0, 0, 0) 到镜像点 (x_i, y_i, h + h - z_i) 的方向向量为 x_i, y_i, h + h - z_i)。
但是,这个方向向量可能需要归一化或简化(即除以最大公约数 gcd(x_i, y_i, 2h - z_i))。
方向向量的简化
我们需要找到一个方向向量 (i, j, k) 使得:
- (i, j, k) 与 (x_i, y_i, h + h - z_i) 成比例。
- gcd(i, j, k) = 1。
因此,可以计算 (x_i, y_i, h + h - z_i) 的最大公约数 g = gcd(x_i, y_i, h + h - z_i),然后方向向量为 (x_i / g, y_i / g, (h + h - z_i) / g)。
注意事项
- gcd 的计算:gcd 是三个数的最大公约数。可以先计算 gcd(x_i, y_i),然后计算 gcd(这个结果, z_mirror)。
- 负数的处理:如果 z_i > h,那么 z_mirror = 2h - z_i 可能是负数。gcd 可以处理负数(因为 gcd(a, b) = gcd(|a|, |b|)),因此可以取绝对值或直接计算。
- 方向向量的方向:题目没有要求方向向量的特定方向(正向或反向),因此比例后的方向向量是正确的。
- z_i = h 的情况:如果 z_i = h,那么 z_mirror = h,方向向量是 (x_i, y_i, h)。这意味着激光直接射向水面上的点 (x_i, y_i, h),然后反射回自身。但根据题目描述,z_i 可以等于 h。