alice132

 

2025.12.20 作业 - # P11951 [科大国创杯初中组 2023] 数数

题目描述

小可可和小多在拼木棍。

他们现在拿到了 \(n\) 根木棍,第 \(i\) 根木棍的长度是 \(a_i\)。他们现在想知道,有多少种在里面选三根木棍的方案,使得这三根木棍能组成一个三角形?

三根木棍能组成一个三角形,当且仅当较短的两根木棍长度和大于最长的那根木棍长度。

输入格式

第一行一个正整数 \(n\),表示木棍的个数。

第二行 \(n\) 个正整数,第 \(i\) 个正整数 \(a_i\) 表示第 \(i\) 根木棍的长度。

输出格式

一行一个整数,表示有多少种选三根木棍的方案,使得这三根木棍能组成一个三角形。

输入输出样例 #1

输入 #1

5
3 2 5 3 4

输出 #1

8

说明/提示

样例 1 解释

可以选择的编号的方案是:\((1,2,4)\)\((1,2,5)\), \((1,3,4)\)\((1,3,5)\)\((1,4,5)\)\((2,3,5)\), \((2,4,5)\)\((3,4,5)\)

数据规模与约定

对于 \(20\%\) 的数据,满足 \(n \leq 100\)

对于 \(40\%\) 的数据,满足 \(n \leq 10^3\)

对于另外 \(20\%\) 的数据,满足 \(a_i \leq 5 \times 10^3\)

对于 \(100\%\) 的数据,满足 \(3 \leq n \leq 8 \times 10^3\)\(1 \leq a_i \leq 10^9\)

题解

  1. 将所有边从小到大排序。
  2. 枚举三角形最小的两条边 \(a_i,a_j\),满足 $ a_i+a_j <a_k$ ,求满足条件的最大下标 \(k\) , 贡献的方案数为 \(k-j-1\) , 区间 $[a_{j+1},a_k] $ 均为合法方案。
#include <bits/stdc++.h>
using namespace std;
int n,a[8003];
int main(){
    cin>>n;
    for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    sort(a+1,a+1+n);
    a[n+1]=2*a[n];
    long long Ans=0;
    for (int i=1;i<n-1;i++) {
        int k=i+2;
        for (int j=i+1;j<n;j++) {
            while (a[i]+a[j]>a[k]) k++;
            //cout<<i<<" "<<j<<" "<<k-j<<endl;
            Ans+=k-1-j;
        }
    }
    cout<<Ans<<endl;
    return 0;
}

posted on 2026-01-22 21:38  alice_ss  阅读(0)  评论(0)    收藏  举报

导航