poj 2891 Strange Way to Express Integers

/*

对于线性同余方程组不满足( m1,m2,...,mk 两两互素)条件的情况:

s ≡ r1 ( mod a1 ) ≡ r2 ( mod a2 ),其中不满足 a1,a2,...,ak 两两互素
可以看作 s=a1*x+r1=a2*y+r2, 即 a1*x-a2*y=r2-r1
方程 a1 * x - a2 * y = r2-r1 有整数解的充要条件是 (r2-r1)%(a1,a2)==0
求出 x 的最小非负整数解.
令 r1'= s=a1*x+r1=a2*y+r2 , a1'= lcm(a1,a2)
则可以将两个方程合并成一个方程: s ≡ r1' ( mod a1')
并继续合并下去,最后 r1 就是方程组的解了

*/


//题意:给出n个同余方程 s = ri (mod ai),求最小的s值,若解不存在则输出-1. 注意ai并不两两互素

#include<iostream> //线性同余方程组,其中不满足 a1,a2,...,ak 两两互素
using namespace std;

long long x,y,q;
void extend_eluid(long long a,long long b) //x*a+y*b=gcd(a,b)=q
{

if(b==0)
{
x=1;y=0;q=a;
}
else
{
extend_eluid(b,a%b);
long long temp=x;
x=y;y=temp-a/b*y;
}
}
int main()
{
long long n,a1,a2,r1,r2;
while(cin>>n)
{
int ok=1;
cin>>a1>>r1;
for(int i=1;i<n;++i)
{
cin>>a2>>r2;
if(!ok)
continue;
extend_eluid(a1,a2);
if( (r2-r1)%q != 0 )
{
ok=0;
continue;
}
x = x * (r2-r1) / q;
int ff = a2 / q ;
x = ( x % ff + ff ) % ff ; //求出x的最小非负整数解
r1 = a1 * x + r1 ;

a1 = ( a1 * a2 ) / q ; //a1=lcm(a1,a2)
}

if(ok)
cout<<r1<<endl;
else
cout<<"-1\n";
}
return 0;
}

posted on 2011-07-22 19:51  sysu_mjc  阅读(128)  评论(0编辑  收藏  举报

导航