孙子定理是中国古代求解一次同余式组(见同余)的方法。是数论中一个重要定理。又称中国余数定理。一元线性同余方程组问题最早可见于中国南北朝时期(公元5世纪)的数学著作《孙子算经》卷下第二十六题,叫做“物不知数”问题,原文如下:
有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?即,一个整数除以三余二,除以五余三,除以七余二,求这个整数。《孙子算经》中首次提到了同余方程组问题,以及以上具体问题的解法,因此在中文数学文献中也会将中国剩余定理称为孙子定理。
定理:
例子:
c代码:
/*中国剩余定理
输入一个n,表示同余式组的同余式的个数
然后依次输入 b[1],...,b[n](即上面的a[i])
以及m[1],...,m[n]
计算 mm=m[1]*...*m[n]
计算M[1] =mm/m[1]...M[n]=mm/m[n];
求M[i]模m[i]的逆元:ni[i]=NI(M[i],m[i])
最后计算x≡ ( ni[1]*M[1]*b[1]+...+ni[n]*M[n]*b[n] )% mm
*/
/*
4
1 5 4 10
5 6 7 11
结果:
x ≡ 2111 (mod 2310)
*/
#include<stdio.h>
int NI(int a,int m);
int main()
{
printf("-------------<中国剩余定理求同余式组的解 >------------------hao--\n\n");
printf("\n说明:\n第一行输入同余式组的同余式的个数n(<20)\n");
printf("第二行依次输入n个b[i]的值\n");
printf("第三行依次输入n个m[i]的值\n");
printf("_________________________________________________________________\n\n");
int n;
int b[20]={0},m[20]={0},M[20]={0},ni[20]={0};
scanf("%d",&n);
getchar();
int i;
//为数组b【】和m【】赋值
for(i=1;i<=n;++i)
{
scanf("%d",&b[i]);
getchar();
}
for(i=1;i<=n;++i)
{
scanf("%d",&m[i]);
getchar();
}
//打印同余式组
printf("\n求解的同余式组为:"); //
for(i=1;i<=n;++i)//
{//
printf("\n\tx ≡ %5d (mod %5d)",b[i],m[i]);//
}//
//计算mm
printf("\n\n 1、计算mm\n\t mm=1") ; //
int mm = 1;
for(i=1;i<=n;++i)
{
mm = mm*m[i];
printf("*%d",m[i]); //
}
//计算M[i]
printf("\n\n 2、计算M[i]:") ; //
for(i=1;i<=n;++i)
{
M[i] = mm/m[i];
printf("\n\t M[%d] = mm/m[%d] = %5d / %5d = %5d",i,i,mm,m[i],M[i]); //
}
//求逆
printf("\n\n 3、求M[i]模m[i]的逆元: 即求解ni[i]*M[i] ≡ 1 (mod = m[i])中的ni[i]") ; //
for(i=1;i<=n;++i)
{
ni[i] = NI(M[i],m[i]) ;
printf("\n\t ni[%d]: %5d %5d≡ 1(mod %5d) ",i,ni[i],M[i],m[i]) ;//
}
//求解X
printf("\n\n 4、求X = (Σni[i]*M[i]*b[i])(mod mm) , 1<= i <=n") ; //
int X = 0;
printf("\n\t X = 0");//
for(i=1;i<=n;++i)
{
X = X + ni[i]*M[i]*b[i] ;
printf("+%d*%d*%d",ni[i],M[i],b[i]);//
}
X = X%mm;
printf(" (mod %d)",mm);//
//输出结果
printf("\n\n因此,最后的结果为:");
printf("\n\t-------- x ≡ %d (mod %d) ---------\n\n",X,mm);
return 0;
}
int NI(int a,int m)
{
int s[100]={0};
int t[100]={0};
int q[100]={0};
int r[100]={0};
s[0] = 1 ; s[1] = 0 ;
t[0] = 0 ; t[1] = 1 ;
r[0] = a ; r[1] = m ;
q[1] = r[0] / r[1] ;
r[2] = r[0] % r[1] ;
r[3] = r[1] % r[2];
int j=2;
while(1)
{
q[j] = r[j-1] / r[j];
r[j+1] = r[j-1] - q[j]*r[j];
s[j] = s[j-2] - q[j-1]*s[j-1] ;
t[j] = t[j-2] - q[j-1]*t[j-1] ;
if(r[j+1]==0) break;
j++;
}
if(s[j]<0) return (m+s[j]);
return s[j];
}
运行