题目描述
有一个特殊的正方形房间,每面墙上都有一面镜子。除西南角以外,每个角落都放有一个接受器,编号为 0, 1,以及 2。
正方形房间的墙壁长度为 p,一束激光从西南角射出,首先会与东墙相遇,入射点到接收器 0 的距离为 q 。
返回光线最先遇到的接收器的编号(保证光线最终会遇到一个接收器)。
图示:
解题思路:
光线很大可能会在这个正方形中反射多次才能到达一个接收器,如果写代码考虑反射问题,则是比较复杂的。那么,反射问题该如何转换呢?
可以转换为在无限个堆叠的相同正方形中传播,说是无限个,其实光线传播的最远距离为p和q的最小公倍数,那么,最多经过的正方形个数就是 p q l c m / p pq_{lcm} / p pqlcm/p个,其中, p q l c m pq_{lcm} pqlcm表示p和q的最小公倍数。
反射问题转换之后,下一个问题就是,堆叠后的正方形,接收器的位置和原正方形中如何对应呢?
可以想象一下,或者自己画示意图看下(画图比较麻烦此处就省略了),由于反射是对称的,那么,如果在第二个正方形的右上角接收到光线,那么对应于原正方形的0号接收器(即左下角);总结一下,奇数个正方形的的左上角和右上角依旧对应于原正方形的左上角和右上角,偶数个正方形的左上角和右上角则对应于原正方形的左下角和右下角。代码如下:
Python代码
class Solution:
def mirrorReflection(self, p: int, q: int) -> int:
# 求最小公倍数函数
def lcm(x, y):
if x%y == 0:
return x
elif y%x == 0:
return y
else:
lcm = x * y
while (x != y):
if x > y:
x = x - y
else:
y = y - x
return int(lcm / x)
pq_lcm = lcm(p, q)
num_box = pq_lcm // p #经过多少个box
num_re = pq_lcm // q #反射了几次 确定终点在左还是右
if num_box % 2 == 1:
if num_re % 2 == 1:
return 1
else:
return 2
else:
if num_re % 2 == 1:
return 0
else:
return None