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\)。
题解
- 将所有边从小到大排序。
- 枚举三角形最小的两条边 \(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;
}
浙公网安备 33010602011771号