相信诸位如果学过小学奥数,一定知道如下这个方程组:
2≡1 mod(3)
9≡2 mod(7)
8≡8 mod(11)
.
.
.
n≡k mod(p)n,k<p且p为素数且互不相同
我们的目的很简单,就是求出满足如上方程的最小整数
然后这就是中国剩余定理qwq。。。
好吧,不扯了,让我们开始写代码吧
实现方法1:暴力枚举
先排序,从头开始,从满足第一个方程的最小数开始,每次加上当前被满足的几个方程的p的乘积(这样每次加上的都是前面几个数的倍数,被加上的部分取模后为0,不会影响已经满足的答案),如果满足当前方程,则更新乘积,求解下一组方程
优点:
既好想,也好写。
缺点:
出题人随手就能卡住,复杂度较高(比如说两个素数分别为2和212370440130137957
),电脑这辈子都算不出来
先看一道例题:
这种思路是能A的
代码:
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; long long a,b,c,d,e,f,g,kkk,n; struct zzzz{ int x,y,z; }ltt[15]; bool cmp(zzzz s,zzzz t) { return s.x>t.x; } int main() { cin>>n; kkk=1; for(a=1;a<=n;a++) { cin>>ltt[a].x>>ltt[a].y; } sort(ltt+1,ltt+n+1,cmp); kkk=ltt[1].x; g=ltt[1].y; f+=2; while(f<=n) { while(1) { if(g%ltt[f].x==ltt[f].y) { kkk=kkk*ltt[f].x; f++; break; } g=g+kkk; } } cout<<g; }
上面不是复杂度太高么?那怎么办呢?
现在我们就要用到另一个东西——不定方程
上面的任意两个方程组可以转变为:
a*x1+p1=b*x2+p2
那么我们移项通分,可以得到:
(p3=p2-p1)
a*x1-b*x2=p3;
这是一个二元一次方程,求解即可