Calculate the maximum common divisor of two numbers A and B. We can think of enumerating each positive integer from [1, min (A, B:
#include<iostream>using namespace std;int gcd(int a,int b){ int ans=1; for(int i=2;i<=min(a,b);++i) { if(a%i==0 && b%i==0) ans=i; } return ans;}int main(){ int a,b; cin>>a>>b; cout<<gcd(a,b); return 0;}
However, when a and B are large, this algorithm is not fast enough. There are faster and more elegant algorithms.
- First, a theorem is given:
Gcd (a, B) = gcd (B, A-B) (a> = B)
Proof:
Set gcd (a, B) = M (M> = 1)
Then a % m = 0, B % m = 0
(A % m-B % m) % m = 0
(A-B) % m = 0
Because a % m = 0, B % m = 0, (a-B) % m = 0, gcd (a, B) = m
Therefore, gcd (a, B, a-B) = m;
The following example shows that gcd (B, a-B) = M, and then gcd (a, B) = gcd (B, A-B) is obtained ).
Set c = A-B
Because gcd (a, B, c) = m;
So gcd (B, c )! A sufficient condition for = m is that there is a number D (D> = 1) so that (B/M) % d = 0 and (C/m) % d = 0 and (A/m) % d! = 0.
The following uses the reverse verification method:
D
(C/M) % d = 0
(A-B)/m) % d = 0
(A/m)-(B/M) % d = 0
(A/m) % d-(B/M) % d = 0
Known (B/M) % d = 0, substituted (A/m) % d = 0
Also known (A/m) % d! = 0, so (A/m) % d results belong to (0, d)
X is (0, D), and X % d cannot be equal to 0. Therefore, this is a conflict.
So there is no such d
Therefore, gcd (B, a-B) = gcd (B, c) = m
Gcd (a, B) = gcd (B, A-B) (a> = B) the theorem has been proved.
Therefore, we can use this algorithm for calculation, where gcd (A, 0) =:
#include<iostream>using namespace std;int gcd(int a,int b){ if(b==0) return a; if(a<b) swap(a,b); return gcd(b,a-b);}int main(){ int a,b; cin>>a>>b; if(a<b) swap(a,b); cout<<gcd(a,b); return 0;}
Of course, when the data size is large, the stack may overflow, so change it to non-recursive mode.
Can it be faster? (Thank you for your proof)
- Then the second theorem is given:
Gcd (a, B) = gcd (B, A-K * B) where K is 0, 1, 2, 3, 4... and a> = K * B
This theorem proves the same as above.
- The following theorem can be obtained through simplification:
Gcd (a, B) = gcd (B, A % B)
This is the moving phase division (Euclidean Algorithm ).
#include<iostream>using namespace std;int gcd(int a,int b){ if(b==0) return a; return gcd(b,a%b);}int main(){ int a,b; cin>>a>>b; cout<<gcd(a,b); return 0;}
Calculate the maximum common divisor gcd (A, B) of two numbers & proves Euclidean Algorithm