中国剩余定理(孙子定理)及其应用

据说是数论四大定理之一,它解决了一个实际问题:

一个整数除以三余二,除以五余三,除以七余二,求这个整数

也就是:

如果你知道同余方程的基本构成,理解同余方程组也就十分容易了

别看百科说了这么多,最有用的就最后一句话

我们接下来给出可以写程序的算法形式:

 ====================================================================

设正整数两两互素,则同余方程组

有整数解。并且在模下的解是唯一的,解为

其中,而的逆元

 ====================================================================

由于POJ1006一直过不了,所以找了一道NYOJ34来演示这个算法

应该没问题

 1 #include<cstdio>
 2 using namespace std;
 3 int a[5],m[5];
 4 int gcd(int a,int b)
 5 {
 6     return b==0?a:gcd(b,a%b);
 7 }
 8 int exgcd(int a,int b,int &x,int &y)  
 9 {  
10     if(b==0) {x=1;y=0;return a;}  
11     else
12     {   
13         int ans=exgcd(b,a%b,x,y);   
14         int t=x; x=y; y=t-(a/b)*y;  
15         return ans;  
16     }  
17 }
18 int crt(int a[],int m[],int n)
19 {
20     int d,x,y,lcm=1,ret=0;
21     for(int i=1;i<=n;i++) lcm=lcm*m[i];//因为互质所以直接这么写了
22     for(int i=1;i<=n;i++)
23     {
24         int kl=lcm/m[i];
25         d=exgcd(kl,m[i],x,y);
26         x=(x%m[i]+m[i])%m[i];
27         ret=(ret+a[i]*x*kl)%lcm;
28     }
29     return ret;
30 }
31 int main()
32 {
33     int x,y,z;
34     scanf("%d%d%d",&x,&y,&z);
35     a[1]=x,a[2]=y,a[3]=z;
36     m[1]=3,m[2]=5,m[3]=7;
37      if(gcd(gcd(x,y),z)==1)
38          printf("%d",crt(a,m,3));
39      else
40          printf("No answer");
41     return 0;
42 }

猜你喜欢

转载自www.cnblogs.com/aininot260/p/9483807.html