一看就是中国剩余定理的题,而且还不一定是互质的,立马就没了思路。。
后来去网上找题解,自己推导了好长时间才有一点懂了这个问题,哎,毕竟数学太弱了。
思路大体是这样的,因为有多个式子,所以就要想办法把他们合并,到最后剩下一个就是答案了。N=x*m1+r1,N=y*m2+r2,所以可以得到x*m1+y*m2=r2-r1;根据扩展欧几里得算法,如果(r2-r1)能整除gcd(m1,m2),那么就有解,否则就无解。先解出x0*m1+y0*m2=gcd(m1,m2)中的x0,y0,然后x=x0*(r2-r1)/gcd(m1,m2),y=y0*(r2-r1)/gcd(m1,m2);带回到最开始的那个式子得到N=x*m1+r1+lcm(m1,m2); 所以更新后的式子的m1=lcm(m1,m2),r1=x*m1+r1;更新到最后,r1即为所求的答案,别忘了把r1化为正的
#include<stdio.h>
__int64 a[10000],b[10000];
__int64 k,x,y;
__int64 f(__int64 n,__int64 m)
{
if(m==0)
{
x=1; y=0;
return n;
}
else
{
__int64 ans=f(m,n%m);
__int64 temp=y;
y=x-(n/m)*y;
x=temp;
return ans;
}
}
int main()
{
__int64 i,t,m1,m2,r1,r2,l;
bool flag=true;
while(scanf("%I64d",&k)!=EOF)
{
flag=true;
scanf("%I64d%I64d",&m1,&r1);
for( i=1;i<k;i++)
{
scanf("%I64d%I64d",&m2,&r2);
t=f(m1,m2); //t为gcd(m1,m2)
if((r2-r1)%t!=0) //不能整除就标记为false
{
flag=false;
continue;
}
x=(r2-r1)/t*x%(m2/t); //x要模一下m2/t,防止下面的r1溢出
r1=r1+m1*x;
m1=m1*m2/t;
}
if(!flag)
printf("-1\n");
else printf("%I64d\n",(r1%m1+m1)%m1); //别忘了把r1化为正的!
}
return 0;
}