题意
有 n n n根棍子,棍子 i i i的长度为 a i a_i ai。想要从中选出三根棍子组成周长尽可能长的三角形。请输出最大的周长,若无法组成三角形输出0.
思路
很容易想到采用三重循环来枚举所有三角形,复杂度为
O
(
n
3
)
O(n^3)
O(n3)。
更好的办法是先对所有边长进行升序排序得到序列
a
1
,
a
2
.
.
.
a
n
a_1,a_2...a_n
a1,a2...an,如果
i
>
j
i>j
i>j,那么
a
i
≥
a
j
a_i\geq a_j
ai≥aj。现在考虑最大边长
a
n
a_n
an:
- 如果 a n < a n − 1 + a n − 2 a_n < a_{n-1} + a_{n-2} an<an−1+an−2,那么最大周长就是 a n + a n − 1 + a n − 2 a_n + a_{n-1} + a_{n-2} an+an−1+an−2
- 如果 a n ≥ a n − 1 + a n − 2 a_n \geq a_{n-1} + a_{n-2} an≥an−1+an−2,说明不可能找到两条更小边使得 a n < a i + a j , i < n , j < n a_n < a_i + a_j,i<n,j<n an<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;
}
如有不当之处欢迎指出!