题目描述
链接:https://ac.nowcoder.com/acm/contest/7610/C
来源:牛客网

从上图可以看出有两种情况
来源:牛客网
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
思路与分析
首先可以发现题目中的m是没有意义的
所以问题可以转化为一个点在多边形B上每次前进a
1.前进边长a一步完成(不经过多边形B的顶点的旋转)
2.前进边长a两步完成(经过多边形B的旋转)
思路:假设不考虑第二种情况下前进的次数+考虑第二种情况多旋转的(也就是计算共经过多少次多边形B的顶点)
先计算第一种情况: 总路程 多边形B的周长:b*n和边长a的最小公倍数(差不多就是一个点在一个圆上每次循环移动a重新回到原点) su(总次数)=总路程/多边形A的边长
第二种情况多旋转的:lcm(a,b)是一个周期,以第一个样例为例,看下图吧,不好解释,x=lcm(a,b)/a
为在这个周期内移动的次数,y=lcm(a,b)为在这个周期内的路程等于y条矩阵B的边长,所以这个周期内有y-1个顶点,所以多旋转的次数为 总次数=su/x(共多少个周期)*(y-1)(顶点数)
AC代码
#include<bits/stdc++.h> using namespace std; #define ll long long ll gcd(ll a,ll b) { return a%b==0?b:gcd(b,a%b); } ll lcm(ll a,ll b)//求最小公倍数 { return a*b/gcd(a,b); } int main() { ll a,m,b,n; scanf("%lld%lld%lld%lld",&a,&m,&b,&n);//su表示要移动的总次数 ll su=lcm(a,b*n)/a,y=lcm(a,b)/a,x=lcm(a,b)/b;//y表示移动lcm(a,b)前进y次 printf("%lld\n",su+su/y*(x-1)); //x表示移动lcm(a,b),经过了x条b边 return 0; }