度度熊拼三角Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1560 Accepted Submission(s): 679 Problem Description 度度熊有 N 根木棒,每根木棒的长度为ai 。
Input 多组数据(不超过10 组),读到EOF结束。
Output 对于每一组数据,输出一个数表示答案。
Sample Input 3 1 1 100 7 1 9 9 90 2 2 4
Sample Output -1 22
Source |
刚看到这道题时的第一反应就是暴力穷举,结果超时,于是想到了与快排进行结合的方法:
1)将数据先从小到大进行排序
2)根据排序后的数据,从前向后遍历(三重for循环,第一层代表三角形的第一条边,第二层代表三角形的第二条边,第三层代表三角形的最后一条边),当前两条边之和小于第三个数时就跳出第三层的循环(三角形的任意两边之和必须大于第三条边),这样可以节省一定的时间
3)根据遍历的结果取最大值即可
想到这种方法后自我感觉应该很随意AC,然而只是自己意淫罢了(还是超时~~)
后来突然灵光一闪:
1)将数据从大到小进行排序
2)根据排序后的数据,仍然从前向后遍历(....),当第一条边减去第二条边的值大于第三条边时不满足条件及时跳出第三层的循环,当满足条件时计算三角形的周长,此时可以跳出所有的循环了,第一个合法的值就是要找的最大周长(不懂的自行脑补吧,懒得敲了...)
3)输出结果
AC代码:
#include<stdio.h>
#include<stdlib.h>
int a[1005];
int cmp(const void *a, const void *b)
{
return *(int *)b - *(int *)a;
}
int isTriangle(int &i,int &j,int &k)
{
if(a[i]+a[j]>a[k] && a[i]+a[k]>a[j] && a[j]+a[k]>a[i])
return a[i]+a[j]+a[k];
return -1;
}
int main()
{
int n,i,j,k,m,t;
while(scanf("%d",&n) != EOF)
{
for(i=0;i<n;i++)
scanf("%d",&a[i]);
m = -1;
qsort(a,n,sizeof(a[0]),cmp);
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
{
for(k=j+1;k<n;k++)
{
if(a[j]+a[k]<=a[i])
break;
t = isTriangle(i,j,k);
m = m > t ? m : t;
}
if(m > 0)
break;
}
if(m > 0)
break;
}
printf("%d\n",m);
}
return 0;
}