有n根長度不同的木棒,隨意選取三根湊一個合法的三角形,求總拼湊方案的數量(2018騰訊軟體開發-後臺開發方向秋招補考試題第三題)
阿新 • • 發佈:2018-12-11
題目:
有n根長度不同的木棒,隨意選取三根湊一個合法的三角形,求總拼湊方案的數量。對於兩個方案,只要有一根木棒的長度不同,則視為不同拼湊方案。
輸入描述
第一行為正數t(0 <= t <= 10),表示測試用例數
接下來每兩行一個測試資料,第一行一個整數n(3 <= n <= 2000)表示木棒數量
第二行n個不一樣的正整數li(1 <= li <= 10^9),表示每根木棒的長度。
輸入描述
對於每一個測試用例,輸出一個正整數表示方案數
示例
2 4 14 21 94 35 6 10 16 87 43 51 75
程式碼
using namespace std; typedef unsigned int T; int triangle_nums(T* data, int size) { int counts = 0; sort(data, data + size); for (int x = 0; x < size-2; ++x){ for (int y = x + 1; y < size - 1; ++y){ T xy = data[x] + data[y]; for (int z = y + 1; z < size; ++z){ if (xy > data[z]){ //if ((data[z] + data[x]) > data[y] && (data[z] + data[y]) > data[x]) ++counts; } else{ break; } } } } return counts; } int main(int argc, char** argv) { int t; int n; ios::sync_with_stdio(false); cin.tie(nullptr); cin >> t; if (t < 1 || t > 10) return 0; T* l = new T[2000]; while (t--){ cin >> n; if (n < 3 || n > 2000){ delete[]l; return 0; } for (int i = 0; i < n; ++i) cin >> l[i]; cout << triangle_nums(l, n) << endl; } delete[]l; return 0; }
一開始使用暴力求解,三層遍歷,然後x+y>z&&y+z>x&&x+z>y。但複雜度太大,達到了n^3,後面超出時間,只通過了50%。後來想到了先從小到大排序(時間複雜度nlog(n))。再進行x+y>z,這樣只要某個z不滿足條件,後續的z也肯定不滿足,就可以提前退出。修改後增加到60%左右,同樣出現了超時,完全沒轍了。最後一分鐘仔細思考發現,如果是已經排序了的,只要確保x+y>z就可以,因為y+z>x&&x+z>y這個時候是肯定滿足的。最後註釋掉程式碼中的一個if就100%了。