【AtCoder】AGC001 Mysterious Light

题目

传送门

题目大意

在一个边长为NN的等边三角形中,你按如图所示(距aaXX单位长的位置)的方法发射一道激光,激光遇到三角形的边或者之前的激光都会反弹,激光回到原点就结束,问一共走了多远。
【AtCoder】AGC001 Mysterious Light

思路

【AtCoder】AGC001 Mysterious Light
在平行四边形DEFBDEFB中,激光由FF开始反射,能够“完整”地反射到HH,然后进入平行四边形DEHGDEHG
在平行四边形DEHGDEHG中,激光由HH开始反射,能够“完整”地反射到DD,发现反射完成。

于是递归求解。
f(a,b)f(a,b)表示在边长为a,ba,b的平行四边形中激光一共走过的距离,则答案为(加上最开始两个轨迹的长度)f(x,Nx)+Nf(x,N-x)+N
如上图,在平行四边形DEFBDEFB中,a=DE,b=EFa=DE,b=EF,所以激光完整走过的距离是FH×2=ab×2FH\times2=\lfloor\dfrac{a}{b}\rfloor\times2
然后激光进入平行四边形DEHGDEHG,在平行四边形DEHGDEHG中,a=EH=b%a,b=DE=aa'=EH=b\%a,b'=DE=a

于是:f(a,b)=ab×2+f(b%a,a)f(a,b)=\lfloor\dfrac{a}{b}\rfloor\times2+f(b\%a,a)

边界很简单,当bbaa的倍数时,说明激光能够回到原点,返回ab×2a\lfloor\dfrac{a}{b}\rfloor\times2-a,注意要减掉一个aa(观察样例)。

注意开long long

代码

#include<cstdio>

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

int main(){
    long long N,X;
    scanf("%lld%lld",&N,&X);
    printf("%lld",N+Solve(X,N-X));
}