基准时间限制:1 秒 空间限制:131072 KB 分值: 0
难度:基础题
一个正整数K,给出K Mod 一些质数的结果,求符合条件的最小的K。例如,K % 2 = 1, K % 3 = 2, K % 5 = 3。符合条件的最小的K = 23。
Input
第1行:1个数N表示后面输入的质数及模的数量。(2 <= N <= 10) 第2 - N + 1行,每行2个数P和M,中间用空格分隔,P是质数,M是K % P的结果。(2 <= P <= 100, 0 <= K < P)
Output
输出符合条件的最小的K。数据中所有K均小于10^9。
Input示例
3 2 1 3 2 5 3
Output示例
23
中国剩余定理:
在这之前,先记住这俩定理,在看下面文字时,有不懂的就想想这俩定理:
定理1:几个数相加,如果只有一个加数,不能被数a整除,而其他加数均能被数a整除,那么它们的和,就不能被整数a整除。
定理2:二数不能整除,若除数扩大(或缩小)了几倍,而除数不变,则其余数也同时扩大(或缩小)相同的倍数(余数必小于除数)。
我国的数学文化历史悠久。我们的祖先从上古末
开化时代开始,经过许多世代,通过大量的生产实践
和生活实际的研究,创造了许多宝贵的数量文献。
《孙子算经》
(大约公元四世纪、晋朝时期成书)中的“物不知其数”问题的解法是中国数学领先于世界的一个典型例子。它便是最早的
“中国剩余定理”。1.《孙子算经》,最早的“中国剩余定理”
“物不知其数”问题:今有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二,问物几何?答曰:二十三。书中问题的奇妙解法是:三三数之剩二,置一百四十;五五数之剩三,置六十三;七七数之剩二,置三十。并之得二百三十三,以二百一十减之即得二十三。
该算法用口诀表达是:“三人同行七十稀,五树梅花廿一枝,七子团圆正半月,除百零五便得知。”意思是:
每3个一数最后剩1个就取5和7的公倍数70(先让他剩1,再用定理2),那么“三三数之剩二个”,就取
二倍
个70得140(定理2);每5个一数最后剩1个就取3和7的公倍数21,那么“五五数之剩三个”
,就取 三倍 个21得63;每7个一数最后剩1个就取3和5的公倍数15,那么“七七数之剩二个”,就取 二倍 个15得30。最后把140,63,30三数相加的和再减去3、5、7的公倍数105×2,即得符合条件的最小数为23。于是就有:70×2+21×3+15×2-105×2=23。
,就取 三倍 个21得63;每7个一数最后剩1个就取3和5的公倍数15,那么“七七数之剩二个”,就取 二倍 个15得30。最后把140,63,30三数相加的和再减去3、5、7的公倍数105×2,即得符合条件的最小数为23。于是就有:70×2+21×3+15×2-105×2=23。
(注意看这里,ai就是每个余数了,ti先不管,Mi是除了当下的除数之外的所有除数之积。ai不用求,Mi好求,这里ti怎么求呢?ti的意义就是设ax+by=1之中的x,而a是上面的Mi,b是当前除数,那么by就相当于b个b个数的话,数y组的意思,a就是
除了当下的除数之外的所有除数之积,由于ai都是质数,所以a是其余除数的最小公倍数,那么求出x就是上面绿字过程。怎么求x也就是ti呢?用exgcd解就行)
代码如下:
#include <cstdio>
typedef long long LL;
LL n,chu[11],yu[11];
LL x,y;
void exgcd(LL a,LL b)//exgcd求不定方程ax+by=gcd(a,b)=1(a,b互质)
{
if(b==0)
{
x=1;
y=0;
return ;
}
exgcd(b,a%b);
LL tmp=x;
x=y;
y=tmp-(a/b)*y;
}
LL chinese()
{
LL allji=1;
for(int i=0;i<n;i++)//先求出所有的除数之积,以便于球下面的mi
{
allji=allji*chu[i];
}
LL ans=0;
for(int i=0;i<n;i++)
{
LL mi=allji/chu[i];
exgcd(mi,chu[i]);//求x ,也就是ti
ans=(ans+(yu[i]*x*mi)%allji)%allji;
}
if(ans<0)//防止结果是负数
{
ans=ans+allji;
}
return ans;
}
int main()
{
scanf("%lld",&n);
for(int i=0;i<n;i++)
{
scanf("%lld%lld",&chu[i],&yu[i]);
}
printf("%lld\n",chinese());
return 0;
}
还有一种写法,也值得学习下(适合小数据):
例7:一个班学生分组做游戏,如果每组三人就多两人,每组五人就多三人,每组七人就多四人,问这个班有多少学生?
题目可以看成,除3余2,除5余3,除7余4。没有同余的情况,用的方法是“逐步约束法”,就是从“除7余4的数”中找出符合“除5余3的数”,就是再7上一直加7,直到所得的数除5余3。得出数为18,下面只要在18上一直加7和5得最小公倍数35,直到满足“除3余2”
4+7=11
11+7=18
18+35=53
题目可以看成,除3余2,除5余3,除7余4。没有同余的情况,用的方法是“逐步约束法”,就是从“除7余4的数”中找出符合“除5余3的数”,就是再7上一直加7,直到所得的数除5余3。得出数为18,下面只要在18上一直加7和5得最小公倍数35,直到满足“除3余2”
4+7=11
11+7=18
18+35=53
摘自:http://blog.csdn.net/qq_32734731/article/details/51890220
#include <cstdio>
typedef long long LL;
LL n,chu[11],yu[11];
int main()
{
scanf("%lld",&n);
for(int i=0;i<n;i++)
{
scanf("%lld%lld",&chu[i],&yu[i]);
}
LL ans=yu[0];
LL lcm=1;
for(int i=0;i<n-1;i++)
{
lcm=lcm*chu[i];
while(ans%chu[i+1]!=yu[i+1])
{
ans=ans+lcm;
}
}
printf("%lld\n",ans);
return 0;
}