题目描述
在数学课上老师教她的三角形知识,她开始从这些木棍中间找三根木棍来组成一个周长最大的三角形,
这时她的兄弟顺溜偷偷的溜了过来,偷走了第i根木棍,现在她想知道现在能够组成周长最大的三角形
的周长是多少?
输入描述:
输出描述:
对于每个询问输出一行表示答案,如果删除木棍后无法组成三角形则输出 -1 。
解题思路与易错分析:
这道题的难点我认为是对于三角行判断(对最长周长的三角形),当然三角行很好判断就是满足任意两边之和大于第三边,任意两边之差小于第三边当然这样写的会很麻烦
下面简绍一下我的思路:我想先让这些木棍按长度排序,当然排序的方式有很多,我这里选择最简单的一种快速排序sort(),但这里有一个问题,就是我们排序后只知道长度而不知道木棍的原顺序,这里的解决方法有很多,我选择结构体struct,建立一个struct中储存木棍的长度与顺序,每个一个结构体作为一个木棍的个体,下面是对可组成最大周长的三角形的方法,上面说过
用sort()排序后,当然这里的sort()你要给第三个参数一个判断函数,sort()排序是对于数组来说,你要比较struct就给出
判断的方式或者方法,当然是一个返回值是bool的函数,木棍按长度排序后,(我这里是升序排列),从后往前遍历这里的三角型的判断方式只需要前面的两个的之和大于第三个(这是数学推到,这里简单说一下,因为是按长度排序,前面的小于后面,所以只要满足前面的两个的之和大于第三个就可以构成三角行,实在理解不了可以自己推推),这样思路就很清晰了,现在要考虑的就是关于如何在不满足条件下遍历下一个,如果满足,跳出循环,直接输出,这里求的周长肯定为最大的,如果不满足,就将最大的一个舍弃,因为第二大的和第三大的和都没最大的大,前面的更不要提了,若满足则输出,不满足则继续,到遍历到最后一个也没有符合的就结束
下面附上我的代码:
#include <iostream>
#include <algorithm>
#define sizes 100005//注意不要写1e+5 数组的长度不能为浮点数
using namespace std;
struct node
{
int len;
int num;
}a[sizes];
bool cmp(node a,node b)
{
return a.len < b.len;
}
int main()
{
int n,q;
cin >> n >> q;
for(int i=1; i <= n; i++)
{
cin >> a[i].len;
a[i].num = i;
}
sort(a+1,a+n+1,cmp);
while(q--)
{
int s,i=n,cn=0;
bool flag = false;
long long int sum=0;
cin >> s;
while(i>=0)
{
if(a[i].num != s)
{
sum += a[i].len;
cn++;
}
if(cn==3)
{
if(a[i].len + a[i+1].len > a[i+2].len)
{
cout << sum << endl;
flag = true;
break;
}
else
{
sum -= a[i+2].len;
cn--;
}
}
i--;
}
if(!flag)cout << -1 << endl;
}
return 0;
}