给定一个长度为 n 的正整数数组 a1,a2,…,an
。
请你计算,一共有多少个三元组 (i,j,k)
(1≤i<j<k≤n),使得 ai⋅aj⋅ak
为最小可能值。
输入格式
第一行包含整数 n
。
第二行包含 n
个正整数 a1,a2,…,an
。
输出格式
一个整数,表示满足条件的三元组的数量。
数据范围
前 3
个测试点满足,3≤n≤6。
所有测试点满足,3≤n≤105,1≤ai≤109
。
输入样例1:
4
1 1 1 1
输出样例1:
4
输入样例2:
5
1 3 2 3 4
输出样例2:
2
输入样例3:
6
1 3 3 1 3 2
输出样例3:
1
按大小关系排列就用组合数就是C几几
假设最小的数有x个
第二小的数有y个
第三小的数有z个
情况1: x>=3 选法,就是从x里面选3个 C (x,3)
情况2: x<3,但x+y>=3, 从y中补齐3个数(x一定要全选) C(y,3-x)
情况3 x+y<3,那就从z中补齐 C(z,1)
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 100010;
int n;
int a[N];
LL C(int a, int b)
{
LL res = 1;
for (int i = a, j = 1; j <= b; i --, j ++ )
res = res * i / j;
return res;
}
int main()
{
scanf("%d", &n);
for (int i = 0; i < n; i ++ ) scanf("%d", &a[i]);
sort(a, a + n);//对所有数排个序
int x = 1;//最小数用x表示
while (x < n && a[x] == a[0]) x ++ ;//统计个数
int y = x + 1;
while (y < n && a[y] == a[x]) y ++ ;
int z = y + 1;
while (z < n && a[z] == a[y]) z ++ ;
z -= y;
y -= x;
LL res;
if (x >= 3) res = C(x, 3);
else if (x + y >= 3) res = C(y, 3 - x);
else res = C(z, 1);
printf("%lld\n", res);
return 0;
}