zoukankan      html  css  js  c++  java
  • hdu 3579 Hello Kiki【中国剩余定理】(模数不要求互素)(模板题)

    <题目链接>

    题目大意:

    给你一些模数和余数,让你求出满足这些要求的最小的数的值。

    解题分析:

    中国剩余定理(模数不一定互质)模板题

    #include<stdio.h>
    using namespace std;
    #define  ll long long
     
    ll  A[11],B[11];//B[i]为余数 
    ll dg,ans;//dg为A[i]的最小公倍数    ans 为最小解 
    void exgcd(ll a, ll b, ll &d, ll&x, ll &y)
    {
        if (!b) {d=a; x=1; y=0;}
        else
        {
            exgcd(b, a%b, d, y, x);
            y-=x*(a/b);
        }
    }
    ll gcd(ll a, ll b)
    {
        if (!b) return a;
        else gcd(b, a%b);
    }
    
    ll china(ll n)
    {
        ll a,b,d,x,y,dm;
        ll c,c1,c2;
        a=A[0]; c1=B[0];
        for (int i=1; i<n; i++)
        {
            b=A[i]; c2=B[i];
            exgcd(a, b, d, x, y);
            dm=b/d;
            c=c2-c1;
            if (c%d) return -1;
            x=((x*c/d)%dm+dm)%dm;//x可能为负
            c1=a*x+c1;
            a=a*b/d;
        }
        
        //求最小公倍数 
        dg=a;//dg是最大公约数
        if (!c1)//考虑c1为0的情况
        {
            c1=1;
            for (int i=0; i<n; i++)
            {
                c1=c1*A[i]/gcd(c1, A[i]);
            }
            dg=c1;//此时dg为最小公倍数
        }
        return c1;//c1为最小的X
    }
    
    int main(){
        int t;
        scanf("%d",&t);
        int ncase=0;
        while(t--){
            int m;
            scanf("%d",&m); 
            
            for(int i=0;i<m;i++)
            scanf("%lld",&A[i]);
            for(int i=0;i<m;i++)
            scanf("%lld",&B[i]);
            ans=china(m);     //利用模板找到满足条件的最小值 
            printf("Case %d: %lld
    ",++ncase,ans);
        }
        return 0;
    }

    2018-08-20

  • 相关阅读:
    改善深层神经网络
    IO操作 第一篇 学习(转载)
    杂谈:收集的一些博文
    杭电2072
    Java数组常用方法
    JAVA中final修饰符小结
    南阳106
    南阳283
    南阳277
    南阳458
  • 原文地址:https://www.cnblogs.com/00isok/p/9507996.html
Copyright © 2011-2022 走看看