有n支棒子,棒子i的長度是ai。
您想從這些棒子中選出三支來做出周長最長的三角形。
請求出能夠做出的最大周長。如果無法做出三角形時請輸出0。
限制條件:
3 ≦ n ≦ 100, 1 ≦ ai ≦ 10^6
暴力法要花O(n^3)的時間。程式碼大概長這樣:(ary是存放的array)
// O(n^3) algorithm.
int ai,aj,ak,aans;
aans = 0;
for(ai = 0; ai < n; ai++){
for(aj = ai + 1; aj < n; aj++){
for(ak = aj + 1; ak < n; ak++){
int len = ary[ai] + ary[aj] + ary[ak];
int ma = max(ary[ai], max(ary[aj], ary[ak]));
int rest = len - ma;
if(ma < rest) aans = max(aans, len);
}
}
}
printf("最大周長:%d\n", aans);
在繞了大圈子以後總算想到了。
解法:
1. 先由小到大排序(正常的演算法可以輕鬆達到O(n log n))
2. 設三根分別是第c、b、a根。當c被選定時,
若存在b、a使三角形成立,
那麼c、c-1、c-2的組合一定是這當中能達到最大周長的。
反過來說,如果c、c-1、c-2的組合無法構成三角形,
那更小的b、a也不可能構成三角形。
所以對每個c來說考慮c、c-1、c-2的組合就好了。
3. ∵ a(c) + a(c-1) + a(c-2) ≧ a(c-1) + a(c-2) + a(c-3)
∴ 讓c從最大的n開始往下,那麼最先找到的三角形必定是周長最大的。
4. 一旦找到三角形成立就可以直接輸出。
如果找到第三根都沒有構成三角形,就輸出0。
5. 這個迴圈只要O(n),所以整體複雜度決定在排序法的複雜度。
Code大概長這樣:
// Complexity is O(n)
void searchC(int* ary){
pmeter = 0;
for(c = n - 1; c >= 2; c--){
// b=c-1; a=c-2;
if( (ary[c] - ary[c-1]) < ary[c-2]){
pmeter = ary[c] + ary[c-1] + ary[c-2]; return;
}
}
}
呼叫前不要忘記要先排序array:(當然認真來說quicksort的worst case是O(n^2)...... )
// comparator
int sort(const void *x, const void *y){
return (*(int*)x - *(int*)y);
}
// 程式中使用C內建的quicksort
// 請記得#include <stdlib.h>
qsort(ary, n, sizeof(int), sort);
沒有留言:
張貼留言