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
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 __int64
using 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;
}