1. 程式人生 > >C 約數(牛客小白月賽10)

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]);
}