AtCoder Grand Contest 001 B - Mysterious Light简单递归

Problem Statement

Snuke is conducting an optical experiment using mirrors and his new invention, the rifle of Mysterious Light.

Three mirrors of length N are set so that they form an equilateral triangle. Let the vertices of the triangle be a,b and c.

Inside the triangle, the rifle is placed at the point p on segment ab such that ap=X. (The size of the rifle is negligible.) Now, the rifle is about to fire a ray of Mysterious Light in the direction of bc.

The ray of Mysterious Light will travel in a straight line, and will be reflected by mirrors, in the same ways as "ordinary" light. There is one major difference, though: it will be also reflected by its own trajectory as if it is a mirror! When the ray comes back to the rifle, the ray will be absorbed.

The following image shows the ray's trajectory where N=5 and X=2.

btriangle.png

It can be shown that the ray eventually comes back to the rifle and is absorbed, regardless of the values of N and X. Find the total length of the ray's trajectory.

Constraints

  • 2≦N≦1012
  • 1≦XN1
  • N and X are integers.

Partial Points

  • 300 points will be awarded for passing the test set satisfying N≦1000.
  • Another 200 points will be awarded for passing the test set without additional constraints.

Input

The input is given from Standard Input in the following format:

N X

Output

Print the total length of the ray's trajectory.

Sample Input 1

5 2

Sample Output 1

12

Refer to the image in the Problem Statement section. The total length of the trajectory is 2+3+2+2+1+1+1=12.

题目大意

光在三角形中的入射方向都是水平向右,光通路也会对光进行反射,求光离开三角形走过的总长度

解题思路

这是一个不停减转化为除的过程。从图中我们可以看出来

第一次反射之前的路程 是X + N - X = N。

之后的路程就是看 能够进行多少个三角形的反射。

每一次的N和X不断改变。当N % x == 0 跳出循环就好了。

C++ AC代码:

#include <iostream>

using namespace std;
long long n, x, ans;
long long cel(long long n, long long x) {
    if(n % x == 0)
        return 2 * n - x;
    ans = n / x * 2 * x + cel(x, n % x);
    return ans ;
}
int main()
{
    while(cin >> n >> x) {
        ans = n + cel(n - x, x);
        cout << ans << endl;
    }

}

JAVA AC代码:

import java.util.Scanner;
public class Main {
public static long cel(long a, long b) {
long ans;
if(a % b == 0)
return 2 * a - b;
ans = a / b * 2 * b + cel(b, a % b);
return ans;
}
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
while(cin.hasNext()) {
long n, x, ans;
n = cin.nextLong();
x = cin.nextLong();
ans = n + cel(n - x, x);
System.out.println(ans);
}
}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值