C 約數(牛客小白月賽10)
阿新 • • 發佈:2019-01-01
連結: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]); }