题面
题目描述
小A有 nnn 根木棒,他想拼一个三角形。但是他也是有要求的,他希望可以拼出周长最大的三角形。
现在给你多组数据,每组数据都是一个这样的问题,请输出每组数据的周长最大的三角形。当然,如果无法拼成三角形,就无需输出最大周长,直接输出 −1-1−1 。
题目输入
本题有多组数据。保证不超过 101010 组。
每次读入一个整数 nnn ,代表木棒的根数,读到 EOF 结束,否则继续读入 nnn 个正整数 aia_iai ,代表每根木棒的长度。
注:若不知道如何实现读到 EOF 结束,可以使用下面的基础代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
while(scandf("%d",&n)!=EOF)
{
//your code
}
return 0;
}
题目输出
对于每组数据,若可以拼成三角形,输出一个数 xxx 代表能拼出的三角形的最大周长,否则直接输出 −1-1−1 。
具体输出操作见样例。
样例
样例输入
3
1 1 100
7
1 9 9 90 2 2 4
样例输出
-1
22
数据范围与提示
读入方法的提示在题目输入。
1≤n≤10001 \le n \le 10001≤n≤1000
1≤ai≤1051 \le a_i \le 10^51≤ai≤105
思路
思路一:暴力枚举
详解
三重循环出三根木棒,判断是否可以围成三角形。
代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int ans=-1,a[1001];
for(int i=1;i<=n;i++) scanf("%d",a+i);
sort(a+1,a+n+1);
for(int i=1;i<=n-2;i++)
for(int j=i+1;j<=n-1;j++)
for(int k=j+1;k<=n;k++)
if(a[i]+a[j]>a[k])
ans=max(ans,a[i]+a[j]+a[k]);
printf("%d\n",ans);
}
return 0;
}
漏洞
注意到 1≤n≤10001 \le n \le 10001≤n≤1000 ,最大可以循环 10910^9109 次,必然超时。
思路二:枚举优化
详解
可以发现,当有两根木棒确定时,第三根木棒的长度也就确定了范围,因为 a[i]+a[j]>a[k] ,所以可以考虑枚举前两根木棒后二分查找满足“任意两边之长大于第三边”的最长的木棒,再打擂台求最大值。
代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int ans=-1;
vector<int> a(n+1,0);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
sort(a.begin(),a.end());
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
{
int k=lower_bound(a.begin()+1,a.end(),a[i]+a[j])-a.begin()-1;
if(k>j) ans=max(ans,a[i]+a[j]+a[k]);
}
printf("%d\n",ans);
}
return 0;
}

1445

被折叠的 条评论
为什么被折叠?



