乙個餘數問題的思考

2021-07-31 04:29:20 字數 2068 閱讀 4243

剛剛在貼吧上看到乙個很簡單的演算法小問題,順便看到了很多人不同的思路。我覺得很有意思,所以也來研究一下。

問題如下:

一筐雞蛋:

1個1個拿,正好拿完。

2個2個拿,還剩1個。

3個3個拿,正好拿完。

4個4個拿,還剩1個。

5個5個拿,還差1個。

6個6個拿,還剩3個。

7個7個拿,正好拿完。

8個8個拿,還剩1個。

9個9個拿,正好拿完。

問:筐裡最少有幾個雞蛋?

題目很簡單,我們可以直接用暴力窮舉法。這當然是最簡單的辦法, 下面是這種方法的kotlin**。執行之後,得到結果為1449。

fun answer1() 

n++}

println(n)

}

當然暴力窮舉雖然簡單,但是效率並不是很高,對於這個問題來說,迴圈執行了1449次。我們可以分析題目特點,簡化迴圈的執行次數。

首先來看看題目,很明顯第一句是廢話,因為任何正整數都可以被1整除。然後是第二句,這表明這個數是乙個奇數。第三句和第九句明顯重複,可以被9整除,那麼必然也可以被3整除,所以只看第九句就可以了。還有第五句需要注意一下,因為這裡是被5除還差1個,所以是還剩4個。我看貼吧裡有些人審題不嚴,導致做了乙個錯誤答案。

經過一番分析,上面的題目就變成了下面這樣的。

奇數

能被9整除

除以4餘1

除以5餘4

除以6餘3

能被7整除

除以8餘1

注意到7和9互質,所以答案必然是63的倍數,而且還是個奇數,所以是奇數倍。所以我們的**可以改進一下。**中的count用於統計迴圈次數,這次結果和上次一樣,但是迴圈次數僅為12次,每次要判斷的條件也減少了很多。

fun answer2

() n += 63 * 2

}println("n=$n,count=$count")

}

當然還可以進一步優化。由於這個數除以5餘4,可以想到該數的個位數字不是4就是9,但是由於是奇數,那麼個位數必然是9,而且這個數是63的倍數。而除以4餘1除以8餘1這兩個條件可以簡化為除以8餘1。所以最後**就變成了這樣,迴圈僅僅迴圈了3次。

fun answer3

() n += 630

}println("n=$n,count=$count")

}

我還看到貼吧上有人說用同餘定理算,但是我比較笨,沒理解怎麼用同餘定理來計算。不過以前我倒是遇到過類似的題目,所以最後來介紹一下。

我遇到的題目類似下面這樣:

乙個數除以2餘1,除以3餘2,除以4餘3,這個數最小是幾?

這個問題倒是有乙個簡便方法,由於餘數恰好和除數只差1,所以如果在被除數上加1,那麼它就可以同時被2、3、4整除,所以這個數最小應該是2、3、4的最小公倍數再減1,所以應該是23 。

回到我們這道題目來說,由於餘數每次都不一樣,所以沒辦法這麼做。不過我想了想,能不能通過加乙個數,讓餘數都變得相同。由於我數學不好,也不懂數論這些專業知識,所以直接用**模擬一下,發現確實可以得到乙個數,讓答案加上這個數以後,所有餘數都相同。這個數是1071,這時候餘數都是0 。kotlin**如下。

fun cal() 

val set = numbers.values.toset()

if (set.size == 1)

}println("這個數是:$n")

}

有了這個數,我們就可以用上面的方法來計算結果了。答案加上1071之後,可以被2-9的所有數整除,所以2-9的最小公倍數再減去1071,就是我們要求的答案。而2-9的最小公倍數也就是5-9的最小公倍數,是2520,再減去前面的1071,正好就是最一開始我們得到的答案1449!

如果大家有更好的思路,也可以告訴我,讓我們互相學習,共同進步!

乙個生產問題引發的思考

前言 最近碰到乙個生產問題,整個處理過程讓我不禁想起幾年前碰到的乙個類似情景,但是結果卻完全不一樣。兩次問題說大不大,說小不小。這次由於我們處理及時,大事化小小事化了而已,然而幾年前的那次事件,卻由於多方原因,鬧得挺大,驚動了某會。由此引發的一些思考和總結吧。問題回顧 排查思路 生產出現這種效能問題...

乙個面試問題的思考

有1000瓶超級名貴的葡萄酒,其中有1瓶有毒。這種毒藥很厲害,哪怕被稀釋了1000000倍還是可以毒死人的。但這個毒藥一定時間後才會毒發,時長是1個月。為了不浪費這些葡萄酒,有100個壯士決定花5周的時間將毒酒找出,他們只希望最多有10個人犧牲,你需要如何安排才能實現。toplanguage 100...

工作遇到乙個簡單問題的思考

最近工作中遇到乙個問題,前前後後共定位了4天 當最後定位到根因的時候,才發現 最後出問題的地方往往是那些你認為最不會出問題的地方 這句話是警示名言,要牢記之。問題場景 有一大片記憶體,從起始位址開始以128kb大小切塊 低位址的64kb記憶體設定為唯讀,高位址的64kb記憶體主要用於任務棧 大概有2...