原题面:https://vjudge.net/problem/POJ-2891
题目大意:给定2n个正整数a1,a2,...,an和r1,r2,...rn,求一个最小的正整数x,满足对任意i<-[1,n]都有x=ai(mod ri),或者给出无解。
输入描述:多组输入,第一行一个整数n,代表元素的个数。接下来n行,每行两个正整数ai,ri,代表第i个二元组。
输出描述:输出满足题目条件的最小的正整数x,如果无解,输出-1。
样例输入:
2 8 7 11 9
样例输出:
31
分析:现在还只会求二元线性同余方程的通解,这个还不会求。现在还只会套个板子求一求,下次补上不套板子的。百度找了一个比较简洁的板子,按照算法进阶上写出来的我没过样例,还是太菜了啊。下次补上自己敲出来的,先用这个板子写一写。
代码:
#include<iostream> #include<cstdio> using namespace std; const int maxn=1e5+7; typedef long long ll; ll a[maxn],r[maxn]; ll exgcd(ll a,ll b,ll& x,ll& y) { if (!b) { x = 1; y = 0; return a; } ll d = exgcd(b, a % b, x, y); ll z = x; x = y; y = z - y * (a / b); return d; } ll gcd(ll a,ll b) { return !b ? a : gcd(b, a % b); } ll China(int len,ll *a,ll *r) { ll M = a[0], R = r[0], x, y; for (int i = 1; i < len; i++) { ll d = exgcd(M, a[i], x, y); if ((R - r[i]) % d != 0) return -1; x = (R - r[i]) / d * x % a[i]; R -= x * M; M = M / d * a[i]; R %= M; } return (R % M + M) % M; } int main() { int n; while (scanf("%d", &n) != EOF) { for (int i = 0; i < n; i++) scanf("%lld%lld", &a[i], &r[i]); ll x = China(n, a, r); printf("%lld ", x); } return 0; }