题目描述
D: 拼接三角形
题目描述
Ocean最爱三角形,现在Ocean手里有n条线段,Ocean现在想知道,这n条线段可以组成多少种三角形。
输入
一个整数n(3≤n≤3000)
接下来n个整数x(1≤x≤10000)
输出
三角形的种类数
样例输入
6
3 2 4 2 5 2
样例输出
5
分析:分:三边不等,等腰三角形,等边三角形,3种情况
代码:
#include <iostream>
#include <cstdio>
#include <map>
#include <algorithm>
#define INF 0x3f3f3f3f
using namespace std;
#define ll long long
int a[3010];
int b[3010];
map<int,int> m;
int bin(int x,int len)//在b数组中找到恰好小于x的元素下标
{
int l=0,r=len-1;
while(l<r-1)
{
int mid=l+r>>1;
if(b[mid]>=x) r=mid-1;
else l=mid;
}
if(b[r]<x) return r;
else if(b[l]<x) return l;
}
int main() {
int n;
cin>>n;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
m[a[i]]++;
}
sort(a,a+n);
int len=1;
b[0]=a[0];
for(int i=1;i<n;i++)
{
if(a[i]!=a[i-1]) b[len++]=a[i];
}
ll sum=0;
for(int i=0;i<len-2;i++)
{
for(int j=i+1;j<len-1;j++)
{
int x=b[i]+b[j];
int id=bin(x,len);
if(id>j) sum+=id-j;
}
}
for(int i=0;i<len;i++)
{
if(m[b[i]]>=2)
{
sum+=i;
int x=2*b[i];
int id=bin(x,len);
if(id>i) sum+=id-i;
}
if(m[b[i]]>=3) sum+=1;
}
cout<<sum<<endl;
return 0;
}