一、整除
乙個整數
a能被另乙個整數
d整除,記作
d|a,意味著存在某個整數k,有
a=kd
。整除的性質:
(1)如果
d|a,
則對於任意整數k有
d|ka
(2)如果
d|a
且d|b
,則d|(a±b)
(3)如果
b|a
且a|b
,則a=b
整除的特殊例子:l若
2能整除
a的最末位,則
2|a;若
4能整除
a的最末兩位,則
4|a;若
8能整除
a的最末三位,則
8|a;……l
若5能整除a
的最末位,則
5|a;若
25能整除
a的最末兩位,則
25|a
;若125
能整除a
的最末位,則
5|a;……l若
3能整除
a的各位數字之和,則
3|a;若
9能整除
a的個位數字之和則
9|a;l若
11能整除
a的偶數字數字之和與奇數字數字之和的差,則
11|a
;二、最大公約數
如果
d|a
並且d>0,
則我們說d是
a的約數
(divisor)
。乙個整數
a的約數最小為
1,最大為
|a|。每個整數
a都可以被其平凡約數1和
a整除。
a的平凡約數也稱為
a的因子
(factor)。如果
d是a的約數並且也是
b的約數,則d是
a與b的公約數
(common divisor),1
是任意兩個整數的公約數。最大公約數
(greatest common divisor)
指所有公約數中最大的那個,a與
b的最大公約數記作
***(a,b)
。定義***(0,0)=0
,***(0,n)=n
。最大公約數的一些性質
(1)***(a,ka) = |a|
(2)對任意整數a與
b,如果
d|a
且d|b
,則d|***(a,b)
(3)對所有整數a和
b以及任意非負數n,
***(an,bn)=n ***(a,b)
(4)對所有正整數d,
a和b,如果
d|ab
並且***(a,d)=1,
則d|b
(5)如果q和
r是a除以
b的商和餘數,即
a=b×
q+r,則
***(a,b)=***(b,r)
三、最小公倍數
如果
d|a
則我們稱a是
d的倍數
(multiple)。如果
m是a的倍數並且也是
b的倍數,則m是
a與b的公倍數
(common multiple)
。任意兩個整數的公倍數有無限多個,其中最小的那個稱為最小公倍數
(least common multiple),a
和b的最小公倍數記作
lcm(a,b)
。lcm(0,0)=0
,lcm(0,n)=0
。公倍數的性質:
lcm(a,b)=a
×b / ***(a,b)
四、演算法分析及實現
1.
最大公約數的實現
公約數演算法的實現其實是直接使用的上面公約數性質中的第
5條,關鍵是要做到深刻理解為什麼該性質能用輾轉相除來實現。即為什麼
a=b×
q+r => ***(a,b)=***(b,r)
首先看乙個例子
***(1001,767)
= ***(767,234)
= ***(234,65)
= ***(65,39)
= ***(39,26)
= ***(26,13)
= ***(13,0)
= 13
那麼為什麼可以這樣呢?
首先,我們要對上面的整除性質
(2)做乙個推論:
如果d|(a+b)
,且d|a
,則d|b。
證明:
利用整除的性質
若d|a
則a=kd
,有:∵
d|(a+b)
則(a+b)=kd 又
d|a,
所以存在乙個整數k1
,有a=k1d
∴(a+b)=kd
k1d + b = kd
b = kd-k1d
又∵k和k
1都是整數,所以
k-k1
也是乙個整數,因此
d|b
證畢。那麼根據以上推論
設***(b,r)=m 則有
m|b
且m|r 假設
q是一整數則
m|(q×b)
那麼m|( q
×b+r ) 令
a=q×
b+r
於是,m|a
也就是說,若
a能表示成q×
b+r
的形式,則
***(a,b)=***(b,r)
那麼為什麼要輾轉相除到
b=0的時候
a就是最小公約數呢?
因為若a
能表示為q×
b+r
的形式,則有
***(a,b)=***(b,r)
,且若b
也能繼續拆解,則能一直如此輾轉下去,一直到
***(0,rn)
時,無法繼續拆解,則說明
rn已經是所能得到的最大公約數。如下面的例子:
***(125,25)
顯然25|125
,所以125 mod 25 = 0,
也就是說會被拆解成25×
5+0的形式,那麼此時,他們的最大公約數顯然就是除數了。
2.
最小公倍數的實現
由於我們已經有最小公倍數的性質
lcm(a,b)=a
×b / ***(a,b)
,所以直接利用這個性質就可以得到最小公倍數
五、實現**(關鍵**)
// (
遞迴版)
int***( int
a, int
b )
// 當然,遞迴呼叫時由於引數的傳遞會導致堆疊的過度參與,因此我們還可以使用迭代形式
// 來實現這個演算法以提高時間和空間效率。雖然效果是有限的,演算法複雜度仍然相同,但是
// 完善本身就是我們追求的目標,所以也將這個**列印如下
int***2( int
a, int
b)
intlcm( int
a, int
b )
兩個最小公倍數版本的效率比較(參考):
執行平台:athlon 64x2 dual 4200+ 2gb記憶體
編譯環境:visual studio 2003.net,windows32 console project, debug version(預設配置)
測試**:
clock_t
clk=clock();
unsigned
intcount=99999999;
while( (count--)!=0 )
clk = clock()-clk;
測試結果:***31563,31500
***215906,15891
從結果可以看出,迭代版比遞迴版高效近一倍,估計是由於在函式呼叫過程還要進行額外的引數入棧,指令位址跳轉(jump)操作,然後在進入函式時,還有將引數出棧,返回值操作等等~由於演算法本身耗時很少,所以這些瑣碎的語言本身的內部操作所帶來的成本也就顯得格外的高。這在較複雜的演算法中體現並不會那麼明顯,但若迭代版比較容易實現,那麼還是盡量使用迭代版來的實在。
(數論)最大公約數和最小公倍數問題
題目描述 description 輸入二個正整數x0,y0 2 x0 100000,2 y0 1000000 求出滿足下列條件的p,q的個數 條件 1.p,q是正整數 2.要求p,q以x0為最大公約數,以y0為最小公倍數.試求 滿足條件的所有可能的兩個正整數的個數.輸入描述 input descri...
最大公約數的計算
在數學中,輾轉相除法,又稱歐幾里得演算法 英語 euclidean algorithm 是求最大公約數的演算法。輾轉相除法首次出現於歐幾里得的 幾何原本 第vii卷,命題i和ii 中,而在中國則可以追溯至東漢出現的 九章算術 輾轉相除法基於如下原理 兩個整數的最大公約數等於其中較小的數和兩數的差的最...
1179 最大的最大公約數
1179 最大的最大公約數 基準時間限制 1 秒 空間限制 131072 kb 分值 40 難度 4級演算法題 給出n個正整數,找出n個數兩兩之間最大公約數的最大值。例如 n 4,4個數為 9 15 25 16,兩兩之間最大公約數的最大值是15同25的最大公約數5。input 第1行 乙個數n,表示...