UVALive6428 A+B【扩展欧几里得算法+GCD】
Regionals 2013 >> Europe - Southeastern
问题链接:UVALive6428 A+B。
问题分析:
可以看作是解方程ax+by=s的问题。
先用扩展欧几里德算法进行计算,求得ax+by=gcd(a,b)=d。若s%d!=0,则无解。
若有解,再进行迭代计算求得最小非负解。
另外一个关键的地方在于需要考虑a,b和s为0的情形。
AC的C++语言程序如下:
/* UVALive6428 A+B */ #include <iostream> using namespace std; typedef long long LL; // 递推法实现扩展欧几里德算法 LL exgcd(LL a, LL b, LL *x, LL *y) { LL x0=1, y0=0, x1=0, y1=1; LL r, q; *x=0; *y=1; r = a % b; q = (a - r) / b; while(r) { *x = x0 - q * x1; *y = y0 - q * y1; x0 = x1; y0 = y1; x1 = *x; y1 = *y; a = b; b = r; r = a % b; q = (a - r) / b; } return b; } /* 递归法:欧几里得算法,计算最大公约数 */ LL gcd(LL m, LL n) { return (m == 0) ? n : gcd(n%m, m); } int main() { LL a, b, s, x, y, d; bool ans; while(cin >> a >> b >> s) { if(a == 0 && b == 0) { ans = (s == 0); } else if(a == 0) { ans = (s % b == 0); } else if(b == 0) { ans = (s % a == 0); } else { d = exgcd(a, b, &x, &y); if(s % d != 0) ans = false; else { LL x0 = b / d; LL y0 = a / d; x= ((s / d % x0) * (x % x0) % x0 + x0)%x0; y= (s - x * a) / b; ans = false; while(y > 0) { if(gcd(x, y) == 1) { ans = true; break; } else { x += x0; y -= y0; } } } } cout << (ans ? "YES" : "NO") << endl; } return 0; }