题意
有nnn根棍子,棍子iii的长度为aia_iai。想要从中选出三根棍子组成周长尽可能长的三角形。请输出最大的周长,若无法组成三角形输出0.
思路
很容易想到采用三重循环来枚举所有三角形,复杂度为O(n3)O(n^3)O(n3)。
更好的办法是先对所有边长进行升序排序得到序列a1,a2...ana_1,a_2...a_na1,a2...an,如果i>ji>ji>j,那么ai≥aja_i\geq a_jai≥aj。现在考虑最大边长ana_nan:
- 如果an<an−1+an−2a_n < a_{n-1} + a_{n-2}an<an−1+an−2,那么最大周长就是an+an−1+an−2a_n + a_{n-1} + a_{n-2}an+an−1+an−2
- 如果an≥an−1+an−2a_n \geq a_{n-1} + a_{n-2}an≥an−1+an−2,说明不可能找到两条更小边使得an<ai+aj,i<n,j<na_n < a_i + a_j,i<n,j<nan<ai+aj,i<n,j<n成立。这是应该将第n条边排除在外。这样最多排除n-2次,就能知道是否能组成三角形。
实现代码
#include <stdio.h>
#include <algorithm>
using namespace std;
const int maxn = 10000 + 5;
int a[maxn];
int getMAXC(int a[], int n) {
sort(a, a + n);
for(int i = n - 1; i >= 2; i--) {
if(a[i] < a[i - 1] + a[i - 2])
return a[i] + a[i - 1] + a[i - 2];
}
return 0;
}
int main() {
int n;
while(scanf("%d", &n) == 1) {
for(int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
printf("%d\n", getMAXC(a, n));
}
return 0;
}
如有不当之处欢迎指出!