zoukankan      html  css  js  c++  java
  • POJ 2891 Strange Way to Express Integers (解一元线性方程组)

    求解一元线性同余方程组:

    x=ri(mod ai) i=1,2,...,k

    解一元线性同余方程组的一般步骤:
    先求出前两个的解,即:
    x=r1(mod a1)     1
    x=r2(mod a2)     2
    1式等价于x=r1+a1*m,2式等价于x=r2+a2*n
    联立可得:m*a1-n*a2=r2-r1=c
    若方程有解,则必须(a1,a2)|c
    设d=(a1,a2),那么如果有解,即可求得
      m*a1-n*a2=d的解,m=m'
    则   m*a1-n*a2=c的解,m0=m'*c/d
    通解m*=m0+(a2/d)*i
    令s=a2/d,则可以求得m的最小解
      m=(m0%s+s)%s
    带入x=r1+a1*m,即可求出解x,设为x0

    接下来,由
    x=r1(mod a1)     1
    x=r2(mod a2)     2
    得出x=x0=r1(mod a1),x=x0=r2(mod a2)
    由定理可得,x=x0(mod [a1,a2])
    设a=lcm(a1,a2),即可将1式和2式合并成一项。
    接下来的就重复上面步骤即可。

    #include <iostream>
    #include <stdio.h>
    
    using namespace std;
    int k;
    //求解方程ax+by=gcd(a,b)
    long long exgcd(long long a,long long b,long long &x,long long &y){
        if(b==0){
            x=1;
            y=0;
            return a;
        }
        long long g=exgcd(b,a%b,x,y);
        long long tmp=x;
        x=y;
        y=tmp-(a/b)*y;
        return g;
    }
    int main()
    {
        long long a1,a2,r1,r2,d,c;
        long long x,y,x0;
        long long s; //s=a2/d;
        while(scanf("%d",&k)!=EOF){
            bool flag=true;
            scanf("%I64d%I64d",&a1,&r1);
            for(int i=1;i<k;i++){
                scanf("%I64d%I64d",&a2,&r2);
                if(!flag)
                    continue;
                /*
                解x=r1(mod a1)
                  x=r2(mod a2)
                相当于
                解不定方程:x*a1+y*a2=r2-r1
                先求解方程:x*a1+y*a2=r2-r1=gcd(a1,a2)
                得出解x,则方程x*a1+y*a2=r2-r1的解x0=x*(r2-r1)/gcd(a1,a2)=x*c/d
                令s=a2/d,那么
                x0的最小解为:x0=(x0%s+s)%s
                即可得出解x=r1+x0*a1
                然后将x赋值给r1,lcm(a1,a2)赋值给a1,继续求解。
                */
                c=r2-r1;
                d=exgcd(a1,a2,x,y);
                if(c%d!=0){
                    flag=false;
                    continue;
                }
                x0=x*c/d;
                s=a2/d;
                x0=(x0%s+s)%s;
                r1=r1+x0*a1;
                a1=a1*a2/d;
            }
            if(flag)
                printf("%I64d
    ",r1);
            else
                printf("-1
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    div+css 兼容 ie6 ie7 ie8 ie9和FireFox Chrome等浏览器方法
    cocos2dx Error:不允许使用继承成员
    NSKeyedArchiver和NSKeydUnarchiver
    Undefined symbols for architecture i386: _OBJC_CLASS_$_SKPSMTPMessage", referenced from: error
    WBShareKit
    PHP(二)
    cocos2d从Url获得图片数据创建CCSprite
    iPhone获取设备的相关信息
    python发人人状态
    [WARN]Warning: Multiple build commands for output file /
  • 原文地址:https://www.cnblogs.com/chenxiwenruo/p/3553163.html
Copyright © 2011-2022 走看看