AGC001B Mysterious Light

本文介绍了一个关于光线在等边三角形内反射的问题及其解决方案。通过模拟光线在平行四边形内的移动过程,给出了一个计算光线最终移动距离的方法。文章详细阐述了算法实现,并附带了C++代码。

传送门

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

一个很简单的题解是 3 ( N − g c d ( N , X ) ) 3(N −gcd(N, X)) 3(Ngcd(N,X))(听说打表找规律可以很快找出来?)。官方题解的图看起来很直观所以也就不打算解释了QAQ

然而我写的模拟…
我们很容易地可以发现光线是在平行四边形中移动的。不妨设短的一条边为a,长的一条边为b。那么下一个平行四边形的边长就成为b%a和a,直到a为0。一次的路程也就显然是 2 a × ⌊ b a ⌋ 2a\times\left \lfloor \dfrac{b}{a}\right \rfloor 2a×ab。代码没直接写取模但是也就是取模了。因为方向是先左上再左下或者先左上再往右的所以到达了过后要减回来。然后一开始两步没有算要加回来。

时间复杂度不清楚,大概和gcd差不多。

#include<cstdio>
#include<algorithm>
#define LL long long
using namespace std;
LL n,x,ans,x1,x2;
int main()
{
	scanf("%lld%lld",&n,&x);
	ans=n;
	x1=x,x2=n-x;
	while(1)
	{
		if(x1<x2) swap(x1,x2);
		if(!x2) break;
		if(x1%x2==0) ans-=x2;
		ans+=x2*(x1/x2)*2;
		x1-=x2*(x1/x2);
	}
	printf("%lld\n",ans);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值