题目地址:
https://leetcode.com/problems/mirror-reflection/
有一个正方形,四面都有镜子,设想左下角有一束光射出,并且打在右边的镜子上,正方形边长是
p
p
p,打到的位置离下边沿的距离是
q
q
q,
p
p
p和
q
q
q都是大于等于
1
1
1的整数。镜子的编号如图所示:
问最后这束光会打到编号为几的镜子上。
设想该正方形向右翻转若干次,再向上翻转若干次。当这束光延长线走到某个顶角的时候,就意味着走到了镜子上。设走到的顶角的高度是 x x x,那么 x x x既是 p p p的倍数(因为是若干个 p p p叠上去的),也是 q q q的倍数(这是由于相似三角形对应边成比例),由于光第一次走到顶角就会走到镜子上,所以 x = [ p , q ] = p q / gcd { p , q } x= [p,q]=pq/\gcd\{p,q\} x=[p,q]=pq/gcd{p,q}。设左下角的编号是 3 3 3,考虑矩阵 A = [ 2 1 3 0 ] A=\begin{bmatrix} 2 & 1\\ 3 & 0 \end{bmatrix} A=[2310],则横向翻转次数是 x / q − 1 x/q-1 x/q−1,当 x / q x/q x/q是奇数的时候,会打在 [ 1 0 ] \begin{bmatrix} 1\\ 0 \end{bmatrix} [10]这条边上,纵向翻转次数是 x / p − 1 x/p-1 x/p−1,当 x / p x/p x/p是奇数的时候会打到 1 1 1上,否则打到 0 0 0上;当 x / q x/q x/q是偶数的时候,会打在 [ 2 3 ] \begin{bmatrix} 2\\ 3 \end{bmatrix} [23]这条边上,但是 ( x / q , x / p ) = 1 (x/q,x/p)=1 (x/q,x/p)=1,所以 x / p x/p x/p必然是奇数,从而 x / p − 1 x/p-1 x/p−1是偶数,所以只能打在 2 2 2上。代码如下:
public class Solution {
public int mirrorReflection(int p, int q) {
int x = p * q / gcd(p, q);
if (x / q % 2 != 0) {
return x / p % 2 != 0 ? 1 : 0;
}
return 2;
}
private int gcd(int x, int y) {
return y == 0 ? x : gcd(y, x % y);
}
}
时空复杂度 O ( 1 ) O(1) O(1)。