ysg 一道简单的数论题

先声明一点,这个题从一套模拟题中选取出来,所以可能会冒犯到原出题人。请谅解

题干:

ysg,yxy,azw 三人正在刷题。

他们每做一题的时间都是一个有理数。

如果在某一时刻,三人同时做完一道 题,那么,他们会开始谈笑风生。

现在,他们想知道,从时刻 0 开始,至少要等多久才能谈笑风生。

输入格式

一行 6 个整数 a1,b1,a2,b2,a3,b3,其中 ysg 每做一道题的时间是 a1/b1,yxy 是 a2/b2,azw 是 a3/b3。不保证 a,b 互质。

输出格式

一行 2 个数 c,d,表示第一次谈笑风生是在时刻 c/d。其中 c,d 互质。

输入样例 3 6 4 5 3 1

输出样例 12 1

这个题一看上去便是gcd和数论一套瞎搞。

可是它的格式有点难搞,其输入输出格式都是分数,所以不能一开始就化为小数(几乎所有的设计小数的题都不能直接化为小数),还有一点见到分数要直接约分,以免爆long long

闲话不多说,我们来看看这道题,我们可以先把题意简化一下就是三人在哪一时刻他们所做的题都是个整数。

很明显,题目的样例意思就是a1时间内做了b1道题,a2时间内做了b2道题,a3时间内做了b3道题。

我们就要先使通分一下,使分母都相同,这样很明显此时在做题都相同的情况下,时间是不同的,我们再求出在当前分数下,最早什么时间相同时

再把相同的时间和相同做的题约分就得到了结果。

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int a1,b1,a2,b2,a3,b3;
inline int gcd(int x,int y){
    if(y>x) swap(x,y);
    if(y==0) return x;
    return gcd(y,x%y);
}
inline void huajian(int &x,int &y){
    int g=gcd(x,y);
    x/=g; y/=g;
}
inline int get_lcm(int a,int b,int c){
    int l1=a*b/gcd(a,b);
    return l1*c/gcd(l1,c);
}
int main()
{
    freopen("ysg.in","r",stdin);
    freopen("ysg.out","w",stdout);
    scanf("%d%d%d%d%d%d",&a1,&b1,&a2,&b2,&a3,&b3);
    huajian(a1,b1);
    huajian(a2,b2);
    huajian(a3,b3);
    int lcm1=get_lcm(b1,b2,b3);
    int lcm2=get_lcm(a1*lcm1/b1,a2*lcm1/b2,a3*lcm1/b3);
    huajian(lcm1,lcm2);
    printf("%d %d
",lcm2,lcm1);
    fclose(stdin); fclose(stdout);
    return 0;
}
原文地址:https://www.cnblogs.com/liuwenyao/p/9386484.html