【AtCoder1980】Mysterious Light(数学模拟)

版权声明:本文为博主原创文章,请随意转载(注明出处)。 https://blog.csdn.net/can919/article/details/82733271

题意

有一个边长为 N(2<=N<=10^12)的由镜子组成的等边三角形,设结点为a,b,c,从ab上取一点p,使得ap=X(1<=X<=N-1),从p水平向右发射一条神秘光线,经过若干次反射,回到p点。这条神秘光线有一个特点,他会在他走过的路径留下一条反射镜(光线会被自己走过的路线反射),求最后回到p点时,光线移动的距离。

题解

发现光线总是在一个平行四边形里走,平行四边形不断缩小,如图

设平行四边形短边为 a ,长边为 b
下一个平行四边形的短边即为 b   m o d   a ,长边为 a ,这次转移走过的路程为 2 a × ( b / a )
直到走到平行四边形边长为0,注意结束时,左后一次行走路程不是 2 a , 是 a ,要减回来一次。

代码

#include<cstdio>
#include<algorithm>
using namespace std;

long long solve(long long a,long long b)
{
    if(a==0)
        return 0;
    long long res=a*(b/a)*2;
    if(b%a==0)
    {
        res-=a;
        return res;
    }
    return res+solve(b%a,a);
}

int main()
{
    long long N,X;
    scanf("%lld%lld",&N,&X);
    long long ans=N+solve(min(X,N-X),max(X,N-X));
    printf("%lld\n",ans);

    return 0;
}

猜你喜欢

转载自blog.csdn.net/can919/article/details/82733271