卡片 \operatorname{卡片} 卡片
题目链接: nowcoder 213147 \operatorname{nowcoder\ 213147} nowcoder 213147
关于这场比赛
到牛客看
题目
Alice 和 Bob 各带来一个正多边形卡片。
Alice 的卡片是边长为
A
A
A 的正
M
M
M 边形,Bob 的卡片是边长为
B
B
B 的正
N
N
N 边形。
Alice 和 Bob 将两张卡片摆放在一起,其中两张卡片并不重叠,并且有至少一个公共顶点和一条公共边。
Alice 喜欢旋转,因此她沿 Bob 的卡片顺时针旋转自己的多边形。
旋转的中心点是多边形公共边上一点,且旋转过程中两张卡片不重叠。
Alice 想知道,在旋转多少次过后,Alice 的正多边形会回到原位置。
输入
一行,四个整数 A , M , B , N A,M,B,N A,M,B,N,含义如题目描述所述。
输出
一行,一个数 A n s Ans Ans,表示 Alice 旋转的次数。
样例输入1
2 4 3 4
样例输出1
8
样例解释1
前两次操作如下图所示:
样例输入2
3 4 4 4
样例输出2
24
样例输入3
2020 1024 2021 1025
样例输出3
828200
数据范围
对于
10
%
10\%
10% 的数据,
M
=
N
=
4
M=N=4
M=N=4,且
A
≤
B
≤
10
A\leq B\leq 10
A≤B≤10;
对于另外
30
%
30\%
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
%
30\%
30% 的数据,
B
B
B 是
A
A
A 的倍数;
对于
100
%
100\%
100% 的数据,
1
≤
A
≤
B
≤
1
0
6
1\leq A\leq B\leq 10^{6}
1≤A≤B≤106,
3
≤
M
≤
1
0
6
3\leq M\leq 10^{6}
3≤M≤106,
3
≤
N
≤
1
0
6
3\leq N\leq 10^{6}
3≤N≤106。
思路
这道题是一道数学题吧。
就是把普通的翻滚和在角落的翻滚分开讨论要弄多少次。
首先可以发现我们完全不用管 Alice 的多边形是多少边的。
普通的翻滚就是把 Bob 的多边形拉成一条圆,问要滚滚多少次才能滚回原来的点。
角落的翻滚就是先求出翻转到 Alice 的多边形与 Bob 的多边形的接壤的边接壤在 Bob 的多边形的最左边时,要到多少次角落,然后有多少次要转的。
(有一次不用转,就是最后一次)
比赛时
想到是数论,但是不知道要分开两个情况讨论。
然后搞了一个奇奇怪怪的东西(当时还觉得能过
弄了个
16.67
16.67
16.67 分。
好像是没有处理转角落中不用转的那一次。(好像
代码
#include<cstdio>
#define ll long long
using namespace std;
ll a, m, b, n, line, linetime, turn, turntime;
ll gcd(ll x, ll y) {
if (!y) return x;
return gcd(y, x % y);
}
int main() {
scanf("%lld %lld %lld %lld", &a, &m, &b, &n);
line = a * (n * b) / gcd(a, (n * b));//不转角要走多少次
linetime = line / a;
turn = a * b / gcd(a, b);
turntime = line / turn * (turn / b - 1);//要转角多少次
printf("%lld", linetime + turntime);
return 0;
}