UVALive6428 A+B【扩展欧几里得算法+GCD】

来源:互联网 发布:政府数据开放 分析 编辑:程序博客网 时间:2024/06/04 20:06

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;}



阅读全文
0 0
原创粉丝点击