• Vijos 1164 曹冲养猪(中国剩余定理)


    P1164曹冲养猪

    描写叙述

    自从曹冲搞定了大象以后,曹操就開始捉摸让儿子干些事业,于是派他到中原养猪场养猪,但是曹冲满不高兴。于是在工作中马马虎虎,有一次曹操想知道母猪的数量,于是曹冲想狠狠耍曹操一把。

    举个样例。假如有16头母猪,假设建了3个猪圈。剩下1头猪就没有地方安家了。假设建造了5个猪圈,但是仍然有1头猪没有地方去,然后假设建造了7个猪圈,还有2头没有地方去。你作为曹总的私人秘书理所当然要将准确的猪数报给曹总。你该怎么办?

    格式

    输入格式

    第一行包括一个整数n (n <= 10) – 建立猪圈的次数,解下来n行,每行两个整数ai, bi( bi <= ai <= 1000), 表示建立了ai个猪圈。有bi头猪没有去处。你能够假定ai,aj互质.

    输出格式

    输出包括一个正整数,即为曹冲至少养母猪的数目。

    例子1

    例子输入1[复制]

    3
    3 1
    5 1
    7 2

    例子输出1[复制]

    16

    题目大意:

    找出最小的x使得x%m[0]=r[0],x%m[1]=r[1]....

    解题思路:
    中国剩余定理(又称孙子定理)是用来求解例如以下方程组的:
    x % m[0] = r[0]
    x % m[1] = r[1]
    x % m[2] = r[2]
    x % m[3] = r[3]
        ......
    (求解的条件是m数组两两互质

    然后我们设M=m[0]*m[1]*m[2]*......*m[n-1]。由于m数组两两互质。所以M/m[i]与m[i]的最大公约数为1。即gcd(M/m[i],m[i])=1

    所以我们要先找到一个数v使得:
    (M/m[i]) * v % m[i] = 1
    (M/m[i]) * v = 1 (mod m[i])……………………①
    因为题目规定。模m[i]的结果不是1,而是r[i]
    所以等式两边要同一时候乘上r[i]。得:
    (M/m[i]) * v * r[i]= r[i] (mod m[i])
    那么这个(M/m[i]) * v * r[i]就是终于答案x的一部分。

    求(M/m[i]) * v * r[i],我们仅仅须要求v就可以。

    那么我们怎样求得v呢?
    观察①式。发现我们仅仅须要求满足
    (M/m[i]) * v + m[i] * t = 1……………………②
    的v值就可以(当中t为随意整数)。

    观察②式,发现事实上②式就是(M/m[i]) * v + m[i] * t = gcd(M/m[i],m[i]),所以运用拓展欧几里得就可以求出v。

    參考代码:

    #include<map>
    #include<stack>
    #include<queue>
    #include<cmath>
    #include<vector>
    #include<cctype>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const double eps=1e-10;
    const int INF=0x3f3f3f3f;
    const int MOD=1e9+7;
    const int MAXN=50;
    typedef long long LL;
    
    int n,m[MAXN],r[MAXN];
    
    LL exgcd(LL a,LL b,LL& x,LL& y)
    {
        if(b==0)
        {
            x=1;
            y=0;
            return a;
        }
        LL r=exgcd(b,a%b,x,y);
        LL t=y;
        y=x-a/b*y;
        x=t;
        return r;
    }
    
    LL china(int* m,int* r,int n)
    {
        LL M=1,re=0,x,y;
        for(int i=0;i<n;i++)
            M*=m[i];
        for(int i=0;i<n;i++)
        {
            LL w=M/m[i];
            exgcd(w,m[i],x,y);
            re=(re+x*w*r[i])%M;
        }
        return (re+M)%M;
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i=0; i<n; i++)
            scanf("%d%d",&m[i],&r[i]);
        printf("%lld
    ",china(m,r,n));
        return 0;
    }


  • 相关阅读:
    rest简单实例
    Rest简介
    java视频
    j2ee开发中的“java容器”和“web容器”有什么区别?
    用Java实现自己的ArrayList
    Java中关于枚举的7种用法
    Java多线程实现自然同步(内含演示案例)
    Java实现简单的文件复制
    Java之自动拆装箱
    写一个SingleTon,(饿最终、懒同步)
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/7096263.html
Copyright © 2020-2023  润新知