数学基础曹冲养猪

it2023-10-14  80

题目描述

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

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

输入格式

第一行包含一个整数 n,n<=10表示建立猪圈的次数;

接下来 n 行,每行两个整数ai ,bi(bi<=ai<=1000),表示建立了 ai 个猪圈,有 bi 头猪没有去处。你可以假定ai,aj  互质。

输出格式

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

样例

样例输入

3 3 1 5 1 7 2

样例输出

16

这是一道中国剩余定理的模板题目。

中国剩余定理:一元线性同余方程组问题最早可见于中国南北朝时期(公元5世纪)的数学著作《孙子算经》卷下第二十六题,叫做“物不知数”问题,原文如下:

有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?即,一个整数除以三余二,除以五余三,除以七余二,求这个整数。《孙子算经》中首次提到了同余方程组问题,以及以上具体问题的解法,因此在中文数学文献中也会将中国剩余定理称为孙子定理。

三三数之剩二,五五数之剩三,七七数之剩二。问物几何?

即,一个整数除以三余二,除以五余三,除以七余二,求这个整数。

除以3余2和除以7余2的数可以写成21n+2。

21n+2除以5余3,要求21n除以5余1。

21n除以5余1,21除以5余1,要求n除以5余1(乘数之余等于余数之乘),则n最小取1。

所以满足“除以3余2,除以5余3,除以7余2”的最小的数是21×1+2=23。

标准解法:先从3和5、3和7、5和7的公倍数中相应地找出分别被7、5、3除均余1的较小数15、21、70,即:

15÷7=2……余1,

21÷5=4……余1,

70÷3=23……余1.

再用找到的三个较小数分别乘以所要求的数被7、5、3除所得的余数的积连加,15×2+21×3+70×2=233. (将233处用i代替,用程序可以求出)

最后用和233除以3、5、7三个除数的最小公倍数.

233÷105=2……余23,

这个余数23就是合乎条件的最小数.

下面曹冲养猪代码:

#include<iostream> #include<cstdio> using namespace std; long long a[11],b[11],n,m=1,ans=0; void read(){//读入数据     cin>>n;     for(long long i=1;i<=n;i++){         cin>>a[i]>>b[i];         m*=a[i];     } } void exgcd(long long a,long long b,long long &d,long long &x,long long &y){     if(b==0){d=a;x=1;y=0;}     else{         exgcd(b,a%b,d,x,y);         long long t=x;x=y;y=t-a/b*y;     } } void intchina(){//中国剩余定理     long long mi,x,y,i,d;     for(i=1;i<=n;i++){         mi=m/a[i];         exgcd(mi,a[i],d,x,y);         ans=((ans+mi*x*b[i])%m+m)%m;     }     cout<<ans<<endl; } int main(){     read();     intchina();     return 0; }  

最新回复(0)