题目出处点这里
思路:
四根木棍摆成等边三角形
即a=b=c+d,所有有两根木棍相等,另外两根长度未知
不妨设相等的两根木棍长度都为i,设另外两根其中一根长度为j,设num[i]为长度为i的木棍的个数
得到:i=i=j+(i-j);也就是四根木棍
1、先讨论长度为i相等的两根木棍
就是从num[i]取出两根,即C(num[i],2)
2、再讨论另外长度为j和i-j的两根木棍
①j == i-j 时,可看作从长度为j的木堆里取两个,即C(num[j],2)
②j != i-j 时,可看作分别从长度为j和i-j的木堆里分别取一个,即C(num[j],1)*C(num[i-j],1)
③为避免重复,控制j < i - j;
完
package violence;
import java.util.Scanner;
public class P2392 {
static Scanner sc;
static int MO = 1000000007;
static int n;//n个数
static int[] num;//存储每个数字出现的个数
static int max = 0;//存储木棍长度最大值
static int temp;//临时变量存储sc.nextInt()
static int sum = 0;
public static void main(String[] args) {
//初始化
sc = new Scanner(System.in);
n = sc.nextInt();
num = new int[5001];
for (int i = 0; i < n; i++) {
temp = sc.nextInt();
if (temp > max) {
max = temp;
}
num[temp]++;
}
/**
* 易知:a=b=c+d
* 一、即先取两支一样长且长度为i的木棍
* 二、再从比i长度小的木棍取两支木棍j、i-j
* ①j == i-j,从相同长度木堆取两个
* ②j != i-j,从不同长度两个木堆分别取一个
* ③为避免取重复,应控制 j < i - j,即j < i / 2
*/
//如果从长度为1的木堆开始取两个,很明显没有这种情况,因此从长度为2的木堆开始取
for (int i = 2; i <= max; i++) {
if (num[i] >= 2) {//此木堆超过两支木棍
int fs = C(num[i], 2) % MO;
//取完两支长短一样的木棍后,开始取另外两根长度未知的
for (int j = 1; j <= i / 2; j++) {
//1、长度一样;那么就在同一木堆取两个
if (j == i - j && num[j] >= 2) {
sum = (sum + fs * C(num[j], 2)) % MO;
}
//2、长度不一样;那么就在两个不同木堆分别取一个
if (j != i - j && num[j] >= 1 && num[i-j] >= 1) {
sum = (sum + fs * C(num[j], 1) * C(num[i-j], 1)) % MO;
}
}
}
}
System.out.println(sum);
}
// 求组合数
// 要么C(n,1) 要么C(n,2)
public static int C(int k, int r) {
if (r == 1) {
return k % MO;
}
return (k * (k - 1) / 2) % MO;
}
}