先上大佬代码:
#include<iostream>
#include<stdio.h>
using namespace std;
long long exgcd(long long a,long long b,long long &x,long long &y){
if(b==0){
x=1,y=0;
return a;
}
long long q=exgcd(b,a%b,y,x);
y-=a/b*x;
return q;
}
int main(){
long long a1,c1,a2,c2,x,y,t;
long long n;
while(cin>>n){
long long flag=1;
cin>>a1>>c1;
for(long long i=1;i<n;i++){
cin>>a2>>c2;
long long q=exgcd(a1,a2,x,y);
if((c2-c1)%q!=0){
flag=0;
}
t=a2/q;
x=((x*(c2-c1)/q)%t+t)%t;
//cout<<x;
c1=c1+a1*x;
a1=a1*(a2/q);
}
if(flag==0){
cout<<"-1"<<endl;
continue;
}
cout<<c1<<endl;
}
return 0;
}
造了一组数据:
n=6;
a[1]=5;a[2]=6;a[3]=7;a[4]=8;a[5]=9;a[6]=10;
c[1]=1;c[2]=2;c[3]=3;c[4]=4;c[5]=5;c[6]=6;
手写测试,写到崩溃,,
在代码上强势贴上牛皮*:
#include<iostream>
#include<stdio.h>
using namespace std;
long long exgcd(long long a,long long b,long long &x,long long &y){
if(b==0){
x=1,y=0;
return a;
}
long long q=exgcd(b,a%b,y,x);
y-=a/b*x;
return q;
}
int main(){
long long a1,c1,a2,c2,x,y,t;
long long n;
while(cin>>n){
cout<<" n="<<n<<endl;
long long flag=1;
cout<<" flag="<<flag<<endl;
cin>>a1>>c1;
cout<<" a1="<<a1<<" c1="<<c1<<endl;
for(long long i=1;i<n;i++){
cout<<"~~ i="<<i<<" i<"<<n<<" ~~"<<endl;
cin>>a2>>c2;
cout<<" a2="<<a2<<" c2="<<c2<<endl;
cout<<" exgcd("<<a1<<","<<a2<<","<<x<<","<<y<<")"<<endl;
long long q=exgcd(a1,a2,x,y);
cout<<" q="<<q<<"=exgcd()"<<endl;
cout<<" (c2-c1)%"<<q<<"="<<(c2-c1)%q<<endl;
if((c2-c1)%q!=0){
flag=0;
}
t=a2/q;
cout<<" t="<<a2<<"/"<<q<<"="<<t<<endl;
cout<<" x=(("<<x<<"*("<<c2<<"-"<<c1<<")/"<<q<<")%"<<t<<"+"<<t<<")%"<<t<<"="<<((x*(c2-c1)/q)%t+t)%t<<endl;
x=((x*(c2-c1)/q)%t+t)%t;
cout<<" c1="<<c1<<"+"<<a1<<"*"<<x<<"="<<c1+a1*x<<endl;
c1=c1+a1*x;
cout<<" a1="<<a1<<"*("<<a2<<"/"<<q<<")="<<a1*(a2/q)<<endl;
a1=a1*(a2/q);
}
if(flag==0){
cout<<"-1"<<endl;
continue;
}
cout<<c1<<endl;
}
return 0;
}
输出结果如下:
虽然不不明白那些式子是怎么推出来的,但是可以看明白其代表的意思:
先取出前两组,让c1保存前两组的解,a1保存余数为c1的除数,将前两组看成一个整体,再与第三组求解,这样
c1保存前三组的解,a1保存余数为的除数,前三组看做一个整体,,,如果有条件不满足,即不满足欧几里得游街的充分必要条件时,flag变为0,无解,否则到最后一步,c1保存的即是全部同余式的解。