本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
【CCPC】2021威海站 J. Circular Billiard Table | 签到
题目链接
题目
Mr. JR is an expert billiard player who has won the championship of BBPC (Billiard Ball Playing Contest). Nowadays, Mr. JR is tired of the ordinary rectangular billiards table and has great interest in the circular billiards table. Specifically, he is thinking about the following problem.
Mr. JR puts a white ball on the edge of the circular billiard table, and uses the club to hit the white ball at the angle of 𝛽(0<𝛽<90). He wants to know how many times the white ball will collide with the edge of the circular billiard table before it returns to the origin for the first time.
The collision between the ball and the table conforms to the law of mechanics, that is, relative to the tangent of the collision point on the table edge, the incident angle is equal to the exit angle (as shown in figure (b)). And there will be no energy loss in the collision (that means the friction between the ball and the table is not considered, as shown in figure (a)).
This problem is too difficult for Mr. JR. Can you help him?
题目大意
有一个圆形的桌子,一个球在桌子的边缘。
如上图所示,球以角度 被发射出去,经过了若干次反射后回到了最初的位置。问至少经过多少次反射后球回到最初位置?无解输出-1。
球在反弹时与桌子的切线形成的反射角等于入射角,且滚动和反弹过程中均无能量损失。
思路
显然不可能无解。由反射角等于入射角和圆的基本性质,可以得到:
即每反弹一次相当于圆沿着圆周移动了 ,则原问题转化为对于方程 ,求 最小正整数解。即让 是 的倍数,则 。输出答案即可。
代码
#include <bits/stdc++.h>
using namespace std;
long long t,a,b;
long long gcd(long long a,long long b)
{
if (b==0) return a;
return gcd(b,a%b);
}
int main()
{
scanf("%lld",&t);
while(t--)
{
scanf("%lld%lld",&a,&b);
long long x=180*b;
long long y=a;
long long g=gcd(x,y);
long long ans=x/g;
printf("%lld\n",ans-1);
}
return 0;
}