题目链接:https://ac.nowcoder.com/acm/problem/213147

到主站看:https://blog.csdn.net/weixin_43346722/article/details/109390755

题目

Alice 和 Bob 各带来一个正多边形卡片。
Alice 的卡片是边长为 的正 边形,Bob 的卡片是边长为 的正 边形。
Alice 和 Bob 将两张卡片摆放在一起,其中两张卡片并不重叠,并且有至少一个公共顶点和一条公共边。
Alice 喜欢旋转,因此她沿 Bob 的卡片顺时针旋转自己的多边形。
旋转的中心点是多边形公共边上一点,且旋转过程中两张卡片不重叠。
Alice 想知道,在旋转多少次过后,Alice 的正多边形会回到原位置。

输入

一行,四个整数 ,含义如题目描述所述。

输出

一行,一个数 ,表示 Alice 旋转的次数。

样例输入1

2 4 3 4

样例输出1

8

样例解释1

前两次操作如下图所示:
在这里插入图片描述

样例输入2

3 4 4 4

样例输出2

24

样例输入3

2020 1024 2021 1025

样例输出3

828200

数据范围

对于 的数据,,且
对于另外 的数据,,且
对于另外 的数据, 的倍数;
对于 的数据,

思路

这道题是一道数学题吧。

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

首先可以发现我们完全不用管 Alice 的多边形是多少边的。

普通的翻滚就是把 Bob 的多边形拉成一条圆,问要滚滚多少次才能滚回原来的点。

角落的翻滚就是先求出翻转到 Alice 的多边形与 Bob 的多边形的接壤的边接壤在 Bob 的多边形的最左边时,要到多少次角落,然后有多少次要转的。
(有一次不用转,就是最后一次)

比赛时

想到是数论,但是不知道要分开两个情况讨论。

然后搞了一个奇奇怪怪的东西(当时还觉得能过
弄了个 分。

好像是没有处理转角落中不用转的那一次。(好像

图片说明

代码

#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;
}