gcd(gong chan dang)(greatest common divisor) 最大公約數,指兩個整數全部公共約數中最大的。ios
首先先上結論,求最大公約數,咱們能夠經過遞歸gcd(a,b)=gcd(b,a%b),gcd(a,0)=a計算,複雜度是logngit
很明顯,這個偉大的結論gcd(a,b)=gcd(b,a%b),就是著名的歐幾里得公式。spa
那麼怎麼證,其實還挺簡單的。咱們把證實分爲兩步驟:code
一、證實gcd(a,b)是b,a%b的一個公約數blog
二、證實這個公約數是最大的。遞歸
一、咱們設gcd(a,b)=d,再令a=k1*d,b=k2*d.get
咱們再設,a=k*b+c(也就是a除以b商k餘c),那麼c就是餘數,也就是a%b.string
講上面那個式子移項,獲得c=a-k*b,而後再把a=k1*d,b=k2*d,這兩個式子裏的a、b帶入式子,獲得:it
c=k1*d-k*k2*d,在提取公因數d,獲得c=(k1-k*k2)*d.這樣就說明,c,也就是a%b有d這個約數,由於開始咱們設b也有d這個約數,因此gcd(a,b)是b,a%b的一個公約數。io
二、如今知道了它是一個公約數,那麼怎麼證它是最大的?(其實感性分析,a%b都變小了,公約數不可能更大呀!)
可是術學是一門嚴謹的學科,咱們要嚴謹證實。咱們知道,c(a%b)=(k1-k*k2)*d,b=k2*d,咱們只須要證實k1-k*k二、k2互質就行了。
這裏能夠用到反證法:咱們假設k1-k*k2=q*t,k2=p*t,而且t>1(也就是那兩個不互質)。
咱們將前面那個式子移項,獲得k1=q*t+k*k2,再把這個k1代到最開始的a=k1*d,獲得a=(q*t+k*k2)*d,再利用乘法分配律,獲得:
a=q*t*d+k*k2*d,咱們這時發現,k2*d不就是最開始的b嗎?,將其帶入,獲得:a=q*t*d+b*d.
這時,咱們再把k2=p*t代入開始的b=k2*d,獲得b=p*t*d,再把這個式子代到a=q*t*d+b*d.獲得了:a=q*t*d+p*t*d.提取公因數:a=(q+p)*t*d
如今,再和b=p*t*d比較,發現他們的最大公因數變成了t*d和開始矛盾,因此假設不成立,反證成功!
好吧,仍是貼一下求最大公約數的代碼吧
#include <iostream> #include <cstdlib> #include <cstring> #include <algorithm> #define REP(i,k,n) for(int i=k;i<=n;i++) #define in(a) a=read() using namespace std; inline int read(){ int x=0,f=1; char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1; for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; return x*f; } inline int gcd(int a,int b){ if(b==0) return a; return gcd(b,a%b); } int main(){ int a,b; in(a),in(b); cout<<gcd(a,b); }