問題:今有物不知其數,三三數之剩二,五五數之剩三,七七數之剩二。問物幾何?
簡單點說就是,存在一個數x,除以3余2,除以5余三,除以7余二,然后求這個數。上面給出了解法。再明白這個解法的原理之前,需要先知道一下兩個定理。
定理1:幾個數相加,如果存在一個加數,不能被整數a整除,那么它們的和,就不能被整數a整除。
定理2:兩數不能整除,若除數擴大(或縮小)了幾倍,而被除數不變,則其商和余數也同時擴大(或縮小)相同的倍數(余數必小於除數)。
以上兩個定理隨便個例子即可證明!
現給出求解該問題的具體步驟:
1、求出最小公倍數
lcm=3*5*7=105
2、求各個數所對應的基礎數
(1)105÷3=35
35÷3=11......2 //基礎數35
(2)105÷5=21
21÷5=4......1
定理2把1擴大3倍得到3,那么被除數也擴大3倍,得到21*3=63//基礎數63
3、105÷7=15
15÷7=2......1
定理2把1擴大2倍得到2,那么被除數也擴大2倍,得到15*2=30//基礎數30
把得到的基礎數加和(注意:基礎數不一定就是正數)
35+63+30=128
4、減去最小公倍數lcm(在比最小公倍數大的情況下)
x=128-105=23
那么滿足題意得最小的數就是23了。一共有四個步驟。下面詳細解釋每一步的原因。
(1)最小公倍數就不解釋了,跳過(記住,這里討論的都是兩兩互質的情況)
(2)觀察求每個數對應的基礎數時候的步驟,比如第一個。105÷3=35。顯然這個35是除了當前這個數不能整除以外都能夠被其他數整除,就是其他數的最小公倍數。相當於找到了最小的起始值,用它去除以3發現正好余2。那么這個基礎數就是35。記住35的特征,可以整除其他數但是不能被3整除,並且余數是2。體現的還不夠明顯,再看下5對應的基礎數。21是其他數的最小公倍數,但是不能被5整除,用21除以5得到的余數是1,而要求的數除以5應該是余1的。所以余數被擴大,就得到了相應的基礎數63。記住這個數的特征,可以被其他數整除但是被5除應該余三。同理,我們得到了第三個基礎數23,那么他的特征就是:可以被其他數整除,但是不能被7整除,並且余數為2。
(3)第三步基礎數加和,為什么要這樣做呢?利用就是上面提到的定理1。
35+63+30=128。對於3來說,可以把63+30的和看作一個整體,應該他們都可以被3整除。看着上面寫出的三個數的特征,運用定理1來說,就是在35的基礎上加上一個可以被3整除的倍數,那么得到的結果依然還是滿足原先的性質的,就是128除以同樣還是余2的。同理,對於5還說,這個數被除之后會剩余3;對於7來說,被除之后剩余2。所以說,我們當前得到的這個數是滿足題目要求的一個數。但是這個數是不是最小的,那就不一定了。
(4)應該不能確定是不是最小的數,這個時候就要用到他們的最小公倍數了。最小公倍數顧名思義,一定是一個同時被幾個數整除的最小的一個數,所以減去它剩余下來的余數還是符合題意要求的。當然也同樣可以運用定理1來解釋,只不過是加法變成了減法,道理還是一樣的。當然具體要不要剪還是要看和lcm的大小關系的。
稍微的總結一下:就是已知m1,m2,m3是兩兩互質的正整數,求最小的正整數x,使它被m1,m2,m3除所得的余數分別是c1,c2,c3。孫子定理的思想便是線分別求出被其中數mi整除余1而被另外兩個數整除的數Mi(i=1,2,3),則所求數之一的便是c1M1+c2M2+c3M3。由此我們可以得到n個兩兩互質數的情況。證明上面已經一步一步給出。
那么,到此為止基本的中國剩余定理的內容我們以及了解了,包括解答方法。那么如何編碼呢?按照上面這個思路去編碼,其實並不難。一共分為四大步。但是,大多數人的困惑在於如何求取基礎數。這里呢,提供兩種方法:
(1)第一種就是一直遞增,直到找到。例如:3的基礎數,35是其他數的最小公倍數。那么就從35開始,一直自增,知道余數為2,便停止(利用while循環)。
(2)第二種方法呢就是輾轉相除法上得來的。這里的例子體現的不夠明顯,應當看看去求取乘法逆元的過程,下面講的內容和乘法逆元有很大的關系,所以還是看看的好。簡單舉個例子:
假設現在三個數分別是14,3,5,它們兩兩互質,且要求的數除以5余3。求5對應的基礎數。有:
42÷5=8......2
5÷2=2......1
所以1=5-2*2=5-2*(42-8*5)=-2*42+17*5
那么-2*42=-84 17*5=85 -84+85=1
把1擴大3倍變成3,則有-84*3=-252也就是5對應的基礎數。
第一點: 基礎數可以是負數,這個之前點到過。//並且下面的解法就是有這樣的。
第二點: 當得到余數為1的時候后面的算式相當於是一個回溯的過程,最后解到-2*42。 但是還只不過是余數是1的情況對應的數,再運用定理2我們就得到了-252這個基礎數。實際上要是看過乘法逆元,這里實際就是乘法逆元的求解過程,而-2也就是42關於15取模的乘法逆元。
模板:
*long long gcd(LL a,LL b) { return b==0?a:gcd(b,a%b); }*/ #include<cstdio> #define ll long long //擴展歐幾里得算法 void gcd(ll a,ll b,ll &d,ll &x,ll &y) { if(b==0){ d=a; x=1,y=0; } else{//else不能省略 gcd(b,a%b,d,y,x); y-=(a/b)*x; } } //中國剩余定理 ll China(int n,ll *m,ll *a) { ll M=1,d,y,x=0; for(int i=0;i<n;i++) M*=m[i]; for(int i=0;i<n;i++){ ll w=M/m[i]; gcd(m[i],w,d,d,y); x=(x+y*w*a[i])%M; } return (x+M)%M; }