• 【NOIP】【洛谷P1029】最大公约数和最小公倍数问题


    问题描述

    输入格式

    输出格式

    样例输入

    3 60

    样例输出

    4

    提示

    数据范围

    题解

    我们知道p*q=gcd(p,q)*lcm(p,q)

    题目已知gcd和lcm,即x0和y0,由此可得到p*q的值。那么只要枚举p,就能得到q=x0*y0/p

    由于q是整数,所以p一定是x0*y0的因数

    从2开始枚举p,若p是x0*y0的因数且gcd(p,q)=x0,则p为满足条件的一种方案


    然而为什么还要满足gcd(p,q)=x0,或者为什么只需满足gcd(p,q)=x0而不需要lcm(p,q)=y0?

    因为若能找到一个p是x0*y0的因数,必能得到一个q,使得p*q==x0*y0,但事实上乘积相同的两个数有很多组(例如2*9=3*6=18),有可能我们找到的这组p,q并不是满足gcd(p,q)=x0,lcm(p,q)=y0的那组,所以我们求出来的p,q还需要满足gcd(p,q)=x0。那么为什么不需要再满足lcm(p,q)=y0呢?因为我们已知gcd(p,q)*lcm(p.q)=p*q=x0*y0,所以只要满足gcd(p,q)=x0,就可以知道lcm(p,q)=y0一定成立


    由样例可知,每一组数总能找到与之相对应的顺序相反的另一组数(3,60和60,3两个数字完全一样只是顺序不同)事实上,一个数的因数是关于它的平方根对称的,即i和n/i一定一个小于sqrt(n)一个大于sqrt(n),那么只要从2枚举到平方根,找到所有满足条件的数,最后结果乘2即为答案

     1 #include <cstdio>
     2 #include <cmath>
     3 int x,y;
     4 int gcd(int a,int b)
     5 {
     6     return b?gcd(b,a%b):a;
     7 }
     8 int main()
     9 {
    10     scanf("%d%d",&x,&y);
    11     if (x==y)
    12     {
    13         printf("1");
    14         return 0;
    15     }
    16     long long n=1ll*x*y,m=sqrt(n);
    17     int i,s=0;
    18     for (i=2;i<m;i++)
    19       if (!(n%i) && gcd(i,n/i)==x)
    20         s++;
    21     printf("%d",s*2);
    22     return 0;
    23 }
  • 相关阅读:
    Retrofit2源码分析
    Android8.0硬件加速的重绘流程
    Android单元测试
    rand5->rand7,rand7->rand10
    快速排序的随机化版本
    快速排序
    亦或实现交换
    在最坏情况下,找到n个元素中第二小的元素需要n+lgn-2次比较
    3*n/2时间内求出最大最小值
    基数排序
  • 原文地址:https://www.cnblogs.com/rabbit1103/p/13783319.html
Copyright © 2020-2023  润新知