acm-最大公約數/最小公倍數 快速演算法
阿新 • • 發佈:2019-02-05
方法一:歐基裡德演算法:
#include <iostream> #include <fstream> using namespace std; int gcd(int, int); int main(int agrc, char*agvc[]) { int m, n; ifstream cin("a.txt"); while (cin >>m >>n) { cout << gcd(m, n) << endl; } system("pause"); return 0; } int gcd(int a, int b) { while (a != b) { if (a > b) a -= b; else b -= a; } return a; }
方法二更快:化歸思想
/*tein 演算法求最大公約數,和歐基裡德演算法相比,效果更好: 主要思想如下: 化歸思想 1.m為奇數時: (1)n也為奇數:gcd(m,n) = gcd((m+n)/2,(m-n)/2) ; (2)n為偶數: gcd(m,n) = gcd(m,n/2) ; 2.m為偶數時: (1) n也為偶數:gcd(m,n) = gcd(m/2,n/2); (2) n為奇數: gcd(m,n) = gcd(m/2,n); 3.m == n 時,gcd(m,n) = m 退出 */ #include <cstdio> #include <iostream> using namespace std; int stein_gcd(int m, int n) { int temp, total = 0; if (m < n) { temp = m; m = n; n = temp; } if (n == 0) return 0; while (m != n) { if (m & 1) /* 如果m 為奇數, 因為奇數的後面總有一個1,所以可以通過與1且一下來判斷是否是偶數*/ { if (n & 1) /* m,n都為奇數*/ { temp = m; m = (m + n) >> 1; n = (temp - n) >> 1; } else { n >>= 1; } } else /* m為偶數 */ { if (n & 1) /*n 為奇數*/ { m >>= 1; /*由於在這個過程中,m可能小於n ,所以要判斷一下*/ if (m < n) { temp = m; m = n; n = temp; } } else { m >>= 1; n >>= 1; total++; /*記錄縮小的倍數*/ } } } m <<= total; /*還原大小*/ return m; } int main(int agrc ,char* agrv[]) { int m, n, max = 0; while (cin >> m >> n) cout << stein_gcd(m, n) << endl; //printf("%d\n", max); return 0; }