題目連結:
題目大意:
給定一正整數 T (T ≦ 5),代表接下來有 T 個測試資料。
每個測試資料的第一列給定一正整數 n (1 ≦ n ≦ 5 × 10 ^ 7),代表有 n 個磁鐵條。第二列有 n 個正整數,分別代表那 n 個磁鐵條的長度(最大不超過10 ^ 9)。
求是否能從這 n 根磁鐵條之中挑出三條組成一個三角形。可以的話,輸出「YES」;反之,輸出「NO」。
範例輸入:
3
3
3 4 5
4
1 5 10 20
3
10 10 10
範例輸出:
YES
NO
YES
解題思維:
我們觀察以下的 n 值:
當 n = 3 ,數字最小、且不能組成三角形的數列為 1、1、2
當 n = 4 ,數字最小、且不能組成三角形的數列為 1、1、2 、3
當 n = 5 ,數字最小、且不能組成三角形的數列為 1、1、2 、3、5
當 n = 6 ,數字最小、且不能組成三角形的數列為 1、1、2 、3、5、8
當 n = 7 ,數字最小、且不能組成三角形的數列為 1、1、2 、3、5、8、13
……由上的趨勢,我們可以看出不能組成三角形的最小數列之規律正是費氏數列。
而費氏數列以指數成長,當 n = 46 時,數列最後一項為 1134903170。但是題目保證給定的磁鐵條長度 < 10 ^ 9,所以當 n > 45 時,保證可以從中挑出三個組成三角形(畢竟最小的情況已經超出範圍,也就不會有更大的情況發生)。
而剩下的 n ≦ 45 的情況,就可以直接窮舉所有的匹配可能性(Cn 取 3,也就是從 n 個物品中挑 3 個)。占用的時間並不長,可以安心去檢查是否有哪三個可以組成三角形。
而三角形組成的充分必要條件就是:兩個較短邊邊長之和 > 第三邊的邊長。所以我們可以先將其排序,方便判斷(不用判斷孰大孰小)。
但是,因為題目給定的資料量實在太大(至少 > 10MB),所以要採取輸出輸入的最佳化。最佳化方式可以參見這裡。而 n > 45 時緊接著輸入的 n 個數字,可以使用
cin.ignore(1e9, '\n')
來快速忽略掉。以上語法意為:忽略掉 10 ^ 9 個字元,除非遇上了換行(此時就會跳出這個用來忽略字元的函式)。
此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。