来源:牛客网
题目描述
Alice和Bob各带来一个正多边形卡片。
Alice的卡片是边长为A的正M边形,Bob的卡片是边长为B的正N边形。
Alice和Bob将两张卡片摆放在一起,其中两张卡片并不重叠,并且有至少一个公共顶点和一条公共边。
Alice喜欢旋转,因此她沿Bob的卡片顺时针旋转自己的多边形。
旋转的中心点是多边形公共边上一点,且旋转过程中两张卡片不重叠。
Alice想知道,在旋转多少次过后,Alice的正多边形会回到原位置。
输入描述:
一行,四个整数A,M,B,N,含义如题目描述所述。
输出描述:
一行,一个数Ans,表示Alice旋转的次数。
示例1
输入
2 4 3 4
输出
8
说明
前两次操作如下图所示:
示例2
输入
3 4 4 4
输出
24
示例3
输入
2020 1024 2021 1025
输出
828200
备注:
对于10%的数据,M=N=4,且
A
≤
B
≤
10
A\leq B\leq 10
A≤B≤10;
对于另外30%的数据,
M
≤
1000
M\leq 1000
M≤1000,
N
≤
1000
N\leq 1000
N≤1000,且
A
≤
B
≤
1000
A\leq B\leq 1000
A≤B≤1000;
对于另外30%的数据,B是A的倍数;
对于100%的数据,
1
≤
A
≤
B
≤
1
0
6
1\leq A\leq B\leq 10^{6}
1≤A≤B≤106 。
解题思路
算出初始位转到第一个周期开始位,走了多少步(一个周期多少步);再算一个gcd*步数就可以算出转到初始位
Code
#include <iostream>
#include <cstdio>
using namespace std;
long long A, M, B, N, g, s, t=1, ans;
long long gcd(long long x, long long y){
int r = x % y;
while (r)
x = y, y = r, r = x % y;
return y;
}
int main(){
scanf ("%lld%lld%lld%lld", &A, &M, &B, &N);
g = B % A , s = B / A;
if (g) s++;//如果这一边没有转完,那么就要拐个弯
while (g)
{
s++, t++;
s += (B - A + g) / A;
g =(B - A + g) % A;
if (g) s++;
}
ans = N / gcd(N, t) * s;
printf ("%lld", ans);
}