Problem 1402 猪的安家(中国余数定理)

来源:互联网 发布:java方法名称 编辑:程序博客网 时间:2024/04/29 06:12

Problem Description

Andy和Mary养了很多猪。他们想要给猪安家。但是Andy没有足够的猪圈,很多猪只能够在一个猪圈安家。举个例子,假如有16头猪,Andy建了3个猪圈,为了保证公平,剩下1头猪就没有地方安家了。Mary生气了,骂Andy没有脑子,并让他重新建立猪圈。这回Andy建造了5个猪圈,但是仍然有1头猪没有地方去,然后Andy又建造了7个猪圈,但是还有2头没有地方去。Andy都快疯了。你对这个事情感兴趣起来,你想通过Andy建造猪圈的过程,知道Andy家至少养了多少头猪。

Input

输入包含多组测试数据。每组数据第一行包含一个整数n (n <= 10) – Andy建立猪圈的次数,解下来n行,每行两个整数ai, bi( bi <= ai <= 1000), 表示Andy建立了ai个猪圈,有bi头猪没有去处。你可以假定(ai, aj) = 1.

Output

输出包含一个正整数,即为Andy家至少养猪的数目。

Sample Input

3
3 1
5 1
7 2

Sample Output

16
点击打开链接

很裸的中国余数定理的应用:
设m1,m2,…mk是两两互素的正数,则对任意的整数b1,b2,…bk,同余方程组
X ≡ b1 (mod m1)  意思是X和b1对m1取余的结果相同
X ≡ b2 (mod m2)
X ≡ bk (mod mk)
n其解为
nX = ((y1*M1*b1)+(y2*M2*b2)+…+(yk*Mk*bk)  )mod m;
n其中
m = m1*m2*…*mk;
Mi = m / mi;
(yi *Mi) mod mi = 1
n如何求yi
因为 Mi 和mi 互质,gcd(Mi, mi)=1
必然存在 yi*Mi + xi*mi = 1(扩展Euclid)


#include <cstdio>#include <set>#include <string>#include <iostream>#include <cstring>#include <algorithm>#define LL __int64using namespace std;LL y[20],mi[20],b[20],m,M[20],n;LL ex_eulicd(LL aa,LL bb,LL &x,LL &y){LL temp,d;if(bb==0){x=1;y=0;return aa;}d=ex_eulicd(bb,aa%bb,x,y);temp=x;x=y;y=temp-aa/bb*y;return d;}int main(){LL i,res;    ///freopen("D://p.txt","r",stdin);//freopen("D:\\oo.txt","w",stdout);while(scanf("%I64d",&n)!=EOF){res=0;m=1;for(i=0;i<n;i++){scanf("%I64d%I64d",&mi[i],&b[i]);m*=mi[i];}for(i=0;i<n;i++)M[i]=m/mi[i];for(i=0;i<n;i++){LL xx,yy;LL d=ex_eulicd(M[i],mi[i],xx,yy);if(xx<=0)xx+=mi[i];//注意出现负数的情况y[i]=xx;}for(i=0;i<n;i++)res+=(y[i]*b[i]*M[i]);printf("%I64d\n",res%m);}    return 0;}


0 0
原创粉丝点击