CodeForces - 817B Makes And The Product(水题+思维) 解题报告 Apare_xzc
CodeForces - 817B Makes And The Product(水题+思维) 解题报告
xzc 2019/3/30
题意:
给一个长度为n(3<=n<=1E5)数列,这个数列中取出三个数,乘积最小,这样的取法有多少种?
Sample:
Input
4
1 1 1 1
Output
4
Input
5
1 3 2 3 4
Output
2
Input
6
1 3 3 1 3 2
Output
1
思路:
- 肯定先从小到大排序,得到前三个为x,y,z
- 我们设数列中所有值为z的元素为b
- 若y!=z,那么答案就是b
- 若y=z但x!=y, 那么答案就是C(2,b)
- 若x=y=z, 那么答案就是C(3,b)
- 注意算组合数的时候要用long long, 不然可能会乘爆
代码:
#include <bits/stdc++.h>
#define Mst(a,b) memset(a,(b),sizeof(a))
#define For(i,a,b) for(register int i=(a);i<=(b);++i)
#define LL long long
using namespace std;
const int maxn = 1e5 + 100;
int a[maxn];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n;
while(cin>>n)
{
For(i,0,n-1) scanf("%d",a+i);
sort(a,a+n);
int ans = 0;
For(i,3,n-1)
{
if(a[i]==a[2]) ++ans;
else break;
}
if(a[1]<a[2])
{
cout<<ans+1<<endl;
continue;
}
if(a[1]==a[2]&&a[0]<a[1])
{
ans += 2;
LL res = 1ll*ans*(ans-1)/2;
cout<<res<<endl;
}
if(a[1]==a[0]&&a[1]==a[2])
{
ans += 3;
LL res = 1ll*ans*(ans-1)*(ans-2)/6;
cout<<res<<endl;
}
}
return 0;
}