做题思路:
1、这道题是的一道暴力枚举题目,可以用桶把数据(下标是这个数字,元素是出现的次数)存储下来之后按照题目题目给的范围枚举两个长度和是边长的木棒(应为是等边三角形,所以肯定有两根木棒等长,剩下两根木棒的长度之和为边长,表示为a = b = c+d,而我们就要枚举c和d <= 5000)
2、这道题要看出来是组合数学(分两种情况):
注意:如果两根木棒等长但是不是同一根也算不同的搭配
1、i == j,就是较短的两根木棒等长,判断桶数组[i] >= 2才可以 并且a[i+i] >= 2满足题意至少四根木棒,那么计算组合的公式就是 (cnt+a[i]*(a[i]-1)/2%mod*a[i+j]*(a[i+j]-1)/2%mod)%mod;
mod就是题目里的1e9+7运用到了取模运算规律,cnt是存的方案数,其余的就是求有几种搭配
这里要枚举a[i]的不同搭配因为这里i==j,所以就是a[i]*(a[i]-1)/2(数学里的握手问题那种规律n(n-1)/2)
这里相同的两根木棒方案数也要求出a[i+j]*(a[i+j]-1)/2 规律是一样的,把他们相乘就是组合总数
2、i != j,那么只用 (cnt+a[i]*a[j]%mod*a[i+j]*(a[i+j]-1)/2%mod)%mod 应为只有a[i+j]长度相同了,直接乘上a[i]*a[j]的总数了
AC代码:
#include<bits/stdc++.h>
using namespace std;
int a[1000000];
const long long mod = 1e9+7;
int main(){
long long n,cnt = 0; cin >> n;
for(int i = 1; i <= n; i++){
int x; cin >> x;
a[x]++;
}
for(int i = 1; i <= 5000; i++){
for(int j = i; j <= 5000; j++){
if(i+j > 5000) break;
if(i == j){
if(a[i] >= 2 && a[i+j] >= 2){
cnt = (cnt+a[i]*(a[i]-1)/2%mod*a[i+j]*(a[i+j]-1)/2%mod)%mod;
}
}
if(i != j){
if(a[i] != 0 && a[j] != 0 && a[i+j] >= 2){
cnt = (cnt+a[i]*a[j]%mod*a[i+j]*(a[i+j]-1)/2%mod)%mod;
}
}
}
}
cout << cnt << endl;
return 0;
}