HOJ 12899 A+B Bucharest, Romania 2013

来源:互联网 发布:2017优化重组数学答案 编辑:程序博客网 时间:2024/06/05 03:55

这题题意灰常清楚不说了。

解法:可知需要用扩展欧几里德,但是并不是所有的x,y都能取得到的,找规律可得必须要互质。。为啥是互质我也不知道如何证明。。据说是因为辗转相减不是互质的无法得出一个a或者一个b,这题难度就在于会超long long,那么是在哪里会超呢?。在于算出一个x,y之后,大多数人肯定就直接乘上了s/gcd了。我也是。。想想,如果gcd是1,那么在数据大的时候必定会超,所以要取模,比如x,对b/gcd取模,然后乘上s/gcd对于b/gcd取模,这样是不会超long long的,如果x小于等于0就再加上b/gcd,y就通过s/gcd-x*a/gcd再除以b/gcd就可以算得了,这样的解就是x>0的第一个解,然后就判断gcd(x,y)是否等于1,x += b/gcd,y-=a/gcd,遍历到y<0结束,如果没有则是no,不然就是yes。

AC代码:

#include <iostream>#include <cstdio>#include <string.h>#include <string>#include <algorithm>#include <cmath>using namespace std;#define ll __int64#define NMAX 1000void gcd(ll a, ll b, ll &d, ll &x, ll &y){    if(!b){d = a; x = 1; y = 0;}    else{gcd(b,a%b,d,y,x);y -= x*(a/b);}}ll ggcd(ll a,ll b){    if(!b) return a;    else ggcd(b,a%b);}int main(){    #ifdef GLQ    freopen("input.txt","r",stdin);//    freopen("o.txt","w",stdout);    #endif // GLQ    ll a,b,s,A,B;    while(~scanf("%I64d%I64d%I64d",&a,&b,&s))    {        if(s < min(a,b))        {            printf("NO\n");            continue;        }        if((a == 1 && s > b)||(b == 1 && s > a)|| a == s || b == s)        {            printf("YES\n");            continue;        }        if(a == 0 && b == 0)        {            printf("NO\n");            continue;        }        if(a == 0)        {            if(s%b == 0) printf("YES\n");            else printf("NO\n");            continue;        }        if(b == 0)        {            if(s%a == 0) printf("YES\n");            else printf("NO\n");            continue;        }        ll x,y,gg,w;        gg = ggcd(a,b);//        cout<<gg<<endl;        if(s%gg)        {            printf("NO\n");            continue;        }        A = a/gg;        B = b/gg;        gcd(A,B,w,x,y);        x = (s/gg)%B*(x%B);        x %= B;        if(x <= 0) x += B;        y = (s/gg - A*x)/B;//        cout<<x<<" "<<y<<endl;        int flag = 0;        while(y > 0)        {//            cout<<x<<" "<<y<<endl;            if(ggcd(x,y) == 1)            {                flag = 1;                break;            }            x += B;            y -= A;        }        if(flag) printf("YES\n");        else printf("NO\n");    }    return 0;}


0 0
原创粉丝点击