zl程序教程

您现在的位置是:首页 >  其它

当前栏目

卡片

卡片
2023-09-27 14:28:26 时间

卡片 ⁡ \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 AB10
对于另外 30 % 30\% 30% 的数据, M ≤ 1000 M\leq 1000 M1000 N ≤ 1000 N\leq 1000 N1000,且 A ≤ B ≤ 1000 A\leq B\leq 1000 AB1000
对于另外 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} 1AB106 3 ≤ M ≤ 1 0 6 3\leq M\leq 10^{6} 3M106 3 ≤ N ≤ 1 0 6 3\leq N\leq 10^{6} 3N106

思路

这道题是一道数学题吧。

就是把普通的翻滚和在角落的翻滚分开讨论要弄多少次。

首先可以发现我们完全不用管 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;
}