C 约数(牛客小白月赛10)

链接:https://ac.nowcoder.com/acm/contest/280/C
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
Actci上课睡了一觉,下课屁颠屁颠的去找数学老师补课,问了老师一个题目:
给出两个数a,b,问a和b的全部公约数是什么?
数学老师一看这道题太简单了,不屑回答,于是就交给了你。
输入描述:
一行两个数a,b.
输出描述:
a和b的全部公约数,每个数字之间空格隔开。
示例1
输入
25 37
输出
1
示例2
输入
25 100
输出
1 5 25
备注:
对于100%的数据,1 ≤ a,b ≤ 1013
题解:
要求两个数的所有公约数,先求两个数最大公约数,因为二者的公约数均小于等于最大公约数gcd,再从最大公约数中查找,这样可以缩短时间。又可以再从sqrt(gcd)中查找,一旦范围中的一个数i可以被gcd整除,那么在gcd/i!=i的情况下gcd/i也是可以被gcd的整除的,可以通过i来找到另一个数 gcd/i再次缩短时间,因为只需要查找sqrt(gcd)范围内的数
AC代码(如有更简便的方法,恳请指出)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
long long a,b,ans[1000005],len=0;
long long gcd(long long a,long long b)
{  return b==0?a:gcd(b,a%b);}//求最大公约数
int main()
{
    scanf("%lld %lld",&a,&b);
    long long Max=max(a,b);
    long long Min=min(a,b);
    long long c=gcd(Max,Min);
    for(int i=1;i<=sqrt(c);i++)//在sqrt(gcd)中查找公约数
    {
        if(c%i==0)//若i能被整除则此数为二者公约数
        {
            ans[++len]=i;
            if(c/i!=i)
            ans[++len]=c/i;//同时可知道对应的sqrt(gcd)%i也为其公约数(在gcd/i!=i的情况下)
        }
    }
    sort(ans+1,ans+len+1);//对所求的公约数进行排序
    for(int i=1;i<=len;i++)
        printf("%lld ",ans[i]);
}

猜你喜欢

转载自blog.csdn.net/basketball616/article/details/85335770