昨天忙着整别的事情,看了每日一题,但是没写博客整理,所以今天整理一下,题目挺不错的,不怎么会,不过是思维暴力(带点技巧)
推理过程:
- 三角形题目,问题要求删去一个值,剩下的能组成的周长最大的三角形。
- 这里三角形的问题用贪心的思想我也是第一次遇到,从大到小排序,3个连在一起,第一个符合的就是最大的,也可以证明(自己写下就明白了)
- 所以我们按照这个规律来解这个题,我们之间暴力循环搜索,表面看上去复杂度是O(q*n),但是实际并没有,因为不可能存在1e5中不超过1e9的数(要符合斐波那契数列,第1e5位可想而知),因此暴力是可以的。
- 所以我们分几种情况就OK,第一个是第一个位置是否被删除,第二个位置是否被删除,第三个位置是否被删除,然后我们判断是否能构成三角形即可。
- 这里可能就超出了n的范围,不过不用担心,后面的都是默认值0,所以并不会影响的
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 100010;
struct solve
{
long long l;
int id;
}a[N];
bool cmp(solve x, solve y){
return x.l > y.l;
}
int main(){
int n, q;
scanf("%d%d",&n,&q);
for (int i = 1; i <= n; i++){
scanf("%lld",&a[i].l);
a[i].id = i;
}
sort(a + 1, a + n + 1,cmp);
int x, y, z;
for (int i = 0; i < q; i ++){
int t;
scanf("%d",&t);
long long res = 0;
for (int i = 1; i <= n - 2; i ++){
if (a[i].id == t) continue;
else if (a[i + 1].id == t){
x = i;
y = i + 2;
z = i + 3;
}
else if(a[i + 2].id == t){
x = i;
y = i + 1;
z = i + 3;
}
else {
x = i;
y = i + 1;
z = i + 2;
}
if (a[y].l + a[z].l > a[x].l){
res = a[y].l + a[z].l + a[x].l;
printf("%lld\n",res);
break;
}
}
if (res == 0){
puts("-1");
}
}
}