令任意固定整数为M,当M/A余a,M/B余b,M/C余c,M/D余d,…,M/Z余z时,这里的A,B,C,D,…,Z为除数,除数为任意自然数(如果为0,没有任何意义,如果为1,在孙子定理中没有计算和探讨的价值,所以,不包括0和1)时;余数a,b,c,d,z为自然整数时。
1、当命题正确时,在这些除数的最小公倍数内有解,有唯一的解,每一个最小公倍数内都有唯一的解;当命题错误时,在整个自然数范围内都无解。
2、当M在两个或两个以上的除数的最小公倍数内时,这两个或两个以上的除数和余数可以定位M在最小公倍数内的具体位置,也就是M的大小。
3、正确的命题,指没有矛盾的命题:分别除以A,B,C,D,…,Z不同的余数组合个数=A,B,C,D,…,Z的最小公倍数=不同的余数组合的循环周期.
运行结果:/***** ACM之中国剩余定理 ********/ /******** written by C_Shit_Hu ************/ ////////////////扩展欧几里得算法的运用/////////////// /****************************************************************************/ /* 由于VC下面无法使用cout或者cin输出64位的整数。 故改用printf. */ /****************************************************************************/ #include<iostream> using namespace std; typedef _int64 llong; llong b[1000],w[1000]; // 扩展欧几里得算法 // 递归的形式 llong extended_euclid(llong a, llong b, llong &x, llong &y) { llong d; if(b == 0) {x = 1; y = 0; return a;} d = extended_euclid(b, a % b, y, x); y -= a / b * x; return d; } // 中国剩余定理 llong chinese_remainder(int len) { llong i, d, x, y, m, n, ret; ret = 0; n = 1; for(i=0; i < len ;i++) n *= w[i]; for(i=0; i < len ;i++) { m = n / w[i]; d = extended_euclid(w[i], m, x, y); ret = (ret + y*m*b[i]) % n; } return (n + ret%n) % n; } int main() { int n,i; llong res; // 输入测试的除数和余数的组数 cout << "输入测试的除数和余数的组数: " ; while (scanf("%d",&n)!=EOF) { // 输入除数和余数 cout << "输入余数和除数:" << endl; for(i=0;i<n;i++) scanf("%I64d%I64d",&b[i],&w[i]); res=chinese_remainder(n); cout << "结果为:" ; printf("%I64d\n",res); cout << "输入测试的除数和余数的组数: " ; } return 0; }