三角形

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K

一、题目内容

题目描述

铁子从森林里收集了n根木棍,她开始将它们按顺序的排成一排,从左到右依次为1到n,她回想起
在数学课上老师教她的三角形知识,她开始从这些木棍中间找三根木棍来组成一个周长最大的三角形,
这时她的兄弟顺溜偷偷的溜了过来,偷走了第i根木棍,现在她想知道现在能够组成周长最大的三角形
的周长是多少?

输入描述

第一行两个整数n和q。(1\leq n,q \leq 10^5)
第二行n个整数表示第i根木棍的长度a_i(1 \leq a_i \leq 10^9)
接下来q行,每行一个整数表示被顺溜偷走的木棍编号。注意每行的事件是独立的,也就是说每一次操作都是对于原来的n根木棍进行的。

输出描述

对于每个询问输出一行表示答案,如果删除木棍后无法组成三角形则输出 -1 。

示例1

输入

6 2
1 2 3 4 5 6
6
5

输出

12
13

二、解题思路

关键:1.能组成三角形的组合;2.最长周长。
可以组成三角形,而且周长最长,那么我们只需要将数组升序或降序,从最大长度的木棍——>最小长度的木棍遍历,只要能组成三角形(任意两边相加大于第三边,由于是有序的数组,因此只需要将小的两个木棍长度和与大的木棍长度比较即可),即是所有木棍能组成的最大周长perimeter(因为从大到小有序遍历),同时记下最大周长的三根木棍的标号数组maxIDS,最后再比较被顺溜顺走的木棍标号,如果标号在maxIDS中,那么排除被顺走的木棍重新遍历,否则输出最大周长perimeter。(在获取最大周长时,我们可以记录下组成最大周长三根木棍的编号,降低遍历次数,但增加了内存开销。)

代码实操

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e5 + 10;
struct Node {
    int id;
    ll l;
    bool friend operator < (Node n, Node m) {
        if (n.l == m.l) return n.id > m.id;
        return n.l < m.l;
    }
}a[MAXN];
  
int n, q;
///最长周长
ll perimeter = -1;
Node maxIDS[3];
 
void solve(int lost) {
    if (perimeter == -1) {
            cout << "-1" << endl;
        } else {
            if (maxIDS[0].id == lost || maxIDS[1].id == lost || maxIDS[2].id == lost) {
                int minL = a[maxIDS[0].l].l;
                int maxIndex = maxIDS[2].l;
                if (maxIDS[0].id == lost) {
                    minL = a[maxIDS[1].l].l;
                }
                  
                int maxL = a[maxIDS[2].l].l;
                if (maxIDS[2].id == lost) {
                    maxL = a[maxIDS[1].l].l;
                    maxIndex = maxIDS[1].l;
                }
                if (maxIDS[0].l > 1) {
                    if (a[maxIDS[0].l - 1].l + minL > maxL) {
                        cout << 1LL * a[maxIDS[0].l - 1].l + minL + maxL << endl;
                    } else {
                        int res = 0;
                        for(int i = maxIndex; i > 1; i--) {
                            if (a[i].id == lost) {
                                if (a[i - 1].l < a[i - 2].l + a[i - 3].l) {
                                    cout << 1LL * a[i - 1].l + a[i - 2].l + a[i - 3].l << endl;
                                    res = 1;
                                    break;
                                }
                            } else if (a[i - 1].id == lost) {
                                if (a[i].l < a[i - 2].l + a[i - 3].l) {
                                    cout << 1LL * a[i].l + a[i - 2].l + a[i - 3].l << endl;
                                    res = 1;
                                    break;
                                }
                            } else if (a[i - 2].id == lost) {
                                if (a[i].l < a[i - 1].l + a[i - 3].l) {
                                    cout << 1LL * a[i].l + a[i - 1].l + a[i - 3].l << endl;
                                    res = 1;
                                    break;
                                }
                            } else {
                                if (a[i].l < a[i - 1].l + a[i - 2].l) {
                                    cout << 1LL * a[i].l + a[i - 1].l + a[i - 3].l << endl;
                                    res = 1;
                                    break;
                                }
                            }
                        }
                        if (!res) cout << "-1" << endl;
                    }
                } else {
                    cout << "-1" << endl;
                }
            } else {
                cout << perimeter << endl;
            }
        }
}
  
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cin >> n >> q;
    for(int i = 0; i < n; i++) {
        cin >> a[i].l;
        a[i].id = i;
    }
    sort(a,a + n);
    for(int i = n - 1; i > 1; i--) {
        if (a[i - 2].l + a[i - 1].l > a[i].l) {
            perimeter = 1LL * a[i].l + a[i - 1].l + a[i - 2].l;
            maxIDS[0].id = a[i - 2].id, maxIDS[0].l = i - 2;
            maxIDS[1].id = a[i - 1].id, maxIDS[1].l = i - 1;
            maxIDS[2].id = a[i].id,     maxIDS[2].l = i;
            break;
        }
    }
    int lost;
    while(q--) {
        cin >> lost;
        lost -= 1;
        solve(lost);
    }
    return 0;
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容