LeetCode858. Mirror Reflection

There is a special square room with mirrors on each of the four walls.  Except for the southwest corner, there are receptors on each of the remaining corners, numbered 01, and 2.

The square room has walls of length p, and a laser ray from the southwest corner first meets the east wall at a distance q from the 0th receptor.

Return the number of the receptor that the ray meets first.  (It is guaranteed that the ray will meet a receptor eventually.)

Example 1:

Input: p = 2, q = 1
Output: 2
Explanation: The ray meets receptor 2 the first time it gets reflected back to the left wall.


  • 我的思路(略笨):

四面都是镜子的墙壁,光线从西南(左下)角出发,射向东边(右边)的镜子,经过多次反射最终会被一个接收器接收(0、1、2)。期间,南北(上下)墙壁镜子的作用只是改变光线的走向,设想一下,如果没有上下两面墙,而无线延伸左右两面墙,那么光线会被一直向上反射。因此,上下两面墙壁镜子会改变光线继续向上或向下反射,而向反方向前进,同时,光线从左边(右边)经过上/下镜子反射到达右边(左边)时,光线在左右两边镜子的触点与上/下镜子的距离之和等于q。

举个例子,假设光线从左边镜子上的A点经过下面镜子的反射到达右边镜子上的B点,A点到下方镜子的距离加上B点到下方镜子的距离之和为q,光线本来是向下反射的,但经过下方镜子的反射之后变为向上反射。现在有两个问题需要解决,如下:

第一,如何判断光线到达接收器? 利用上面的例子,p减去B点到下方镜子的距离再除以q,如果能除尽,则光线到达接收器,否则,光线会经过上方镜子的反射,改变方向,继续向下反射。

第二,如何判断光线到达哪个接收器? 光线最终达到的接收器只可能为0、1和2,到达接收器时可以分为两种情况,此时光线正往上反射或者正往下反射,如果光线是向上的,那么只会到达1或2,如果是向下的,只会到达0(题目说明光线一定会到达接收器,因此向下的光线一定会到达接收器0)。用flag参数代表光线的走向,一开始光线是向上的,flag = 0, 每一次走到上面的尽头,会反方向向下反射,flag++。d代表光线被反射到左右两面墙上的次数,即光线在左右两面镜子上的触点的总数,一开始光线从左下角出发,d为0,射向右边镜子,d加1,接着在反射到左边镜子,d再加一,可以看出,如果最终停止的时候,光线方向向上,且d为奇数,则到达接收器1,d为偶数到达接收器2,如果光线向下,则一定到达接收器0。

int mirrorReflection(int p, int q) {
    int remain = 0;
    int flag = 0;
    int multi = 0;
    int d = 0;
    
    if(q == 0)
        return 0;
    if(q == p)
        return 1;
 
    remain = p % q;
    multi = p/q;
    d += multi;
    
    while(remain != 0)
    {
        flag++;
        d++;
        remain = q - remain;
        multi = (p - remain)/q;
        d += multi;
        remain = (p - remain)%q;
    }
    
    if(flag%2 == 0)
    {
        if(d%2 == 0)
            return 2;
        else
            return 1;
    }
    else
    {
        return 0;
    }      
}

  • 别人的思路(smart):

如上所述,如果没有上下两面镜子,光线会一直向上反射,这两面镜子的作用仅仅是改变了光线的走向而已。那么可以这样理解,假设没有上下两面镜子,无限延长左右两边的镜子长度,光线一直向上反射。同时,可以通过光线走过的纵向距离来判断光线是否到达接收点,如果此距离是p的奇数倍,那么光线到达上面的接收器,若此距离是p的偶数倍则光线到到下面的接收器,即接收器0。变量d记录光线与左右镜子接触的次数,同上,可根据d来判断光线到达接收器1和2。如果距离为p的奇数倍且d为奇数,则到达接收器1,若d为偶数则到达接收器2。

int mirrorReflection(int p, int q) {
    int dist = 0;
    int d = 0;
    int remain;
    
    while(1)
    {
        d++;
        dist += q;
        remain = dist%(2*p);
        
        if(remain == p)
        {
            if(d%2 == 1)
                return 1;
            else
                return 2;
        }
        if(remain == 0)
            return 0;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值