洛谷 P2152 [SDOI2009]SuperGCD
阿新 • • 發佈:2018-09-14
oid mem sdoi2009 syn char s sync tdi 代碼 整數
題意簡述
求兩個整數a,b的最大公約數0 < a , b ≤ 10 ^ 10000。
題解思路
如果 a % 2 == 0 && b % 2 == 0 gcd(a,b) = gcd(a / 2, b / 2) * 2
如果 a % 2 == 0 && b % 2 != 0 gcd(a,b) = gcd(a / 2, b);
如果 a % 2 != 0 && b % 2 == 0 gcd(a,b) = gcd(a, b / 2);
如果 a % 2 != 0 && b % 2 != 0 gcd(a,b) = gcd(a - b, b);
代碼
#include <cstring> #include <iostream> using namespace std; struct Number { int a[100000]; int c; Number& operator=(const Number& rhs) { c = rhs.c; for (register int i = 1; i <= c; ++i) a[i] = rhs.a[i]; return *this; } }n1, n2, ans, xx; char st[100000]; bool b1, b2; void print(const Number &x) { if (!x.c) {cout << 0 << endl; return;} for (register int i = x.c + 1; --i; ) cout << x.a[i]; cout << endl; } bool compare(const Number &x, const Number &y) { if (x.c != y.c) return x.c < y.c; for (register int i = x.c + 1; --i; ) if (x.a[i] != y.a[i]) return x.a[i] < y.a[i]; return 0; } void _swap(Number &x, Number &y) { Number t; t = x; x = y; y = t; } void div(Number &x) { if (x.a[x.c] == 1) x.a[x.c] = 0, x.a[--x.c] += 10; for (register int i = x.c; i; --i) if (x.a[i] & 1) { x.a[i] /= 2; x.a[i - 1] += 10; } else x.a[i] /= 2; } void mul(Number &x, const Number &y) { Number c; memset(c.a, 0, sizeof c.a); c.c = x.c + y.c - 1; for (register int i = 1; i <= x.c; ++i) for (register int j = 1; j <= y.c; ++j) { c.a[i + j - 1] += x.a[i] * y.a[j]; c.a[i + j] += c.a[i + j - 1] / 10; c.a[i + j - 1] %= 10; } while (c.a[c.c + 1]) ++c.c; _swap(c, x); } void sub(Number &x, const Number &y) { for (register int i = 1; i <= y.c; ++i) { x.a[i] -= y.a[i]; if (x.a[i] < 0) { x.a[i] += 10; x.a[i + 1] -= 1; } } int xx = y.c + 1; while (x.a[xx] < 0) x.a[xx] += 10, x.a[++xx] -= 1; while (!x.a[x.c] && x.c > 0) --x.c; } int main() { ans.a[++ans.c] = 1; xx.a[++xx.c] = 2; ios::sync_with_stdio(0); cin >> st; n1.c = strlen(st); for (register int i = n1.c; i; --i) n1.a[i] = st[n1.c - i] - '0'; cin >> st; n2.c = strlen(st); for (register int i = n2.c; i; --i) n2.a[i] = st[n2.c - i] - '0'; if (compare(n1, n2)) _swap(n1, n2); while (n2.c) { while (!(n1.a[1] & 1) && !(n2.a[1] & 1)) { mul(ans, xx); div(n1); div(n2); } if (!(n1.a[1] & 1)) div(n1); else if (!(n2.a[1] & 1)) div(n2); else sub(n1, n2); if (compare(n1, n2)) _swap(n1, n2); } mul(ans, n1); print(ans); }
洛谷 P2152 [SDOI2009]SuperGCD