在這個突飛猛進的互聯網時代中,但萬變不離其宗的是,「算法」是其重要基石。要編寫高效率的程序,就須要優化算法。不管開發工具如何進化,熟識並能靈活運用算法仍然是對程序員的基本要求。程序員
這裏爲那些已經學習過排序、搜索等知名算法,並想要學習更多有趣的算法,進一步提高編程技巧的工程師們準備了四道數學謎題形式的問題。這四道趣題分青銅、黃金、鉑金,鑽石級別。算法
請各位先通讀問題描述,並動手編寫程序嘗試解題。在這個過程當中,具體的實現方法是其次,更重要的是思考「經過哪些步驟來實現纔可以解決問題」。post
爲了你們更好的享受解題樂趣,把「答案」和「解析」放在了最後。開發工具
Q1:倔強青銅3d
嘗試用編程解決問題htm
難度係數:★
優秀的掃地機器人
(IQ:80 目標時間:20分鐘)
如今有不少製造商都在賣掃地機器人,它很是有用,能爲忙碌的咱們分擔家務負擔。不過咱們也很難理解爲何掃地機器人有時候會反覆清掃某一個地方。
假設有一款不會反覆清掃同一個地方的機器人,它只能先後左右移動。舉個例子,若是第1 次向後移動,那麼連續移動3 次時,就會有如下9 種狀況(如圖 )。又由於第1 次移動能夠是先後左右4 種狀況,因此移動3 次時所有路徑有9×4 = 36 種。
※ 最初的位置用0 表示,其後的移動位置用數字表示。
(移動路徑事例)
(ps:最初三次的移動方向很自由,從第四次開始,座標有些方向就不能移動啦)
Q2:榮耀黃金
解決簡單問題體會算法效果
難度係數:★★
朋友的朋友也是朋友嗎
(IQ:90 目標時間:25分鐘)
「六度空間理論」很是有名。大概的意思是1 我的只須要經過6 箇中間人就能夠和世界上任何1 我的產生間接聯繫。本題將試着找出數字的好友(這裏並不考慮親密指數)。
假設擁有一樣約數(不包括1)的數字互爲「好友」,也就是說,若是兩個數字的最大公約數不是1,那麼稱這兩個數互爲好友。
從1~N 中任意選取一個「合數」,求從它開始,要經歷幾層好友,才能和其餘全部的數產生聯繫(所謂的「合數」是指「有除1 以及自身之外的約數的天然數」)。
舉個例子,N = 10 時,1~10 的合數是四、六、八、九、10 這5 個。
若是選取的是10,那麼10 的好友數字就是公約數爲2 的四、六、8這3 個。而9 是6 的好友數字(公約數爲3),因此10 只須要通過2 層就能夠和9 產生聯繫(如圖 )。若是選取的是6,則只需通過1 層就能夠聯繫到四、八、九、10 這些數字。所以N = 10 時,不管最初選取的合數是什麼,最多通過2 層就能夠與其餘全部數產生聯繫。
(N=10的時候)
問題: 求從1~N 中選取7 個合數時,最多通過6 層就能夠與其餘全部數產生聯繫的最小的N。
Q3:尊貴鉑金
優化算法實現高速處理
難度係數:★★★
優雅的IP 地址
(IQ:100 目標時間:30分鐘)
可能大部分讀者都清楚,IPv4 中的IP 地址是二進制的32 位數值。不過,這樣的數值對咱們人類而言可讀性比較差,因此咱們一般會以8 位爲1 組分割,用相似192.168.1.2 這種十進制數來表示它。
這裏,咱們思考一下十進制數0~9 這10 個數字各出現1 次的IP 地址(像正常狀況同樣,省略每組數字首位的0。也就是說,不能像192.168.001.002 這樣表示,而要像192.168.1.2 這樣來表示)。
問題: 求用二進制數表示上述形式的IP 地址時,能使二進制數左右對稱的IP 地址的個數(用二進制數表示時不省略0,用完整的32 位數表示)。 (ps:IPv4的IP地址用十進制表示時,以點號分割的各部分數字都在0~255這個範圍內。能夠經過求「比特列爲8位且左右對稱」的數值,並將其設置在以點號分割的各部分上來解題。)
Q4:永恆鑽石
改變思路讓程序速度更快
難度係數:★★★★
異性相鄰的座次安排
(IQ:130 目標時間:60分鐘)
回想起學生時期調座位的時候,咱們的內心老是會小鹿亂撞。想必不少人都對誰會坐本身旁邊這件事莫名地激動吧?
這裏咱們考慮一種「先後左右的座位上必定都是異性」的座次安排。也就是說,像圖右側那樣,先後左右都是同性的座次安排是不符合要求的(男生用藍色表示,女生用灰色表示)。(座位安排示例)
問題: 假設有一個男生和女生分別有15 人的班級,要像圖26 那樣,排出一個6×5的座次。求知足上述條件的座次安排共多少種(先後或者左右鏡像的座次也看做不一樣的安排。另外,這裏不在乎具體某個學生坐哪裏,只看男生和女生的座次安排)? (ps:剪枝能夠有效的縮小搜索範圍哦)
~~~~~~~~~~~~~~~~~~~~~~~~~華麗麗的分割線~~~~~~~~~~~~~~~~~~~~~~~~
使人激動的答案來啦~
Q1答案:324932
詳細解析:用座標(0, 0) 表示最初的位置。從這個原點開始,避開已經走過的座標,使機器人前進。用深度優先搜索就能夠實現邏輯,如圖所示。
Q2答案:55(知足條件的組合爲:【4,26,39,55,35,49】)
詳細解析:要解決這個問題,首先要正確理解問題中出現的詞。首先是「合數」。
其次是「公約數」這個詞。小學的時候,咱們就作過求最大公約數的題。公約數的意思就是「共同的約數」。這裏,擁有共同約數的數字互爲「好友」,那麼就須要求最大公約數非1 的狀況。
從1~N 中選取7 個合數,且「最多通過6 層」,那麼能夠得知,咱們要找的是「由2 個數相乘獲得的數字」的組合。這樣的話,乘法運算中的這2 個數就會成爲公約數。
舉個例子,選出a~h 這些數。簡單地說就是,當7 個數字分別是如下的形式時,通過6 層就能與其餘全部數產生聯繫。
a × b, b× c, c× d, d × e, e × f, f× g, g ×h
※這裏a~h 這些數字必須「互質」。
更進一步考慮,也能夠像本題中的例子同樣,把第1 個數字設置成「平方數」(即4),也就是說變成下面這樣的組合更好。
a × a, a × b, b × c, c × d, d × e, e × f, f × g
末尾若是一樣設置成平方數就會變得更小,也就是變成下面這樣的組合。
a × a, a × b, b × c, c × d, d × e, e × f, f × f
Q3答案:8個
詳細解析:按照題意,用十進制數表示時要使用0~9 這10 個數字各1 次,那麼最高位是除0 之外的9 種狀況,而其餘各個數位可分別使用0~9 這10個數字各1 次,其排列組合一共9!(9 的階乘)種,因此總共要遍歷9×9! 種,也就是3265920 種狀況。
要想求左右對稱的二進制數,能夠經過把16 位的二進制數逆序排列,並將結果與該16 位的二進制數自己拼合,即生成32 位數來求得。由於是16 位,因此全量搜索時只須要遍歷65536 種狀況便可。