Educational Codeforces Round 23 problem b
题意:给你n个数,让你从中找到i<j<k,使得a[i]*a[j]*a[k]的乘积尽可能的小,求问满足这样的情况的i,j,k有多少种。
hint : 高中排列数学知识。
题解:统计每个数的次数,我们定义一个map来保存每个数的次数,并且将读入数组按从小到大的顺序排好序,我们只关注排好序数组的最前面的三个元素,而最前面的三个元素的值无非就会有以下几种情况:
1. 三个元素相等 那么ans就是C(cnt[a[0]],3)。
2.三个元素不等 。那么ans就是cnt[a[0]]*cnt[a[1]]*cnt[a[2]]
3 头两个元素相等,但与第三个元素不相等 。那么答案是C(cnt[a[0]],2)*cnt[a[2]]
4.后面两个元素相等,但与第一个元素不相等。那么答案是cnt[a[0]]*C(cnt[a[1]],2)
然后这题就做完辣,还有什么不懂的地方可以看看代码,或者在评论区留言,一起学习进步 !!
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <cmath> #include <cstdlib> #include <ctime> #define PB push_back #define fst first #define sec second #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define ms(a,x) memset(a,x,sizeof(a)) typedef long long LL; #define pi pair < int ,int > #define MP make_pair using namespace std; const double eps = 1E-8; const int dx4[4]={1,0,0,-1}; const int dy4[4]={0,-1,1,0}; const int inf = 0x3f3f3f3f; const int N=1e5+10; LL a[N]; int main() { int n;cin>>n; map<long long ,long long>cnt; for (long long i=0;i<n;i++) { cin>>a[i]; cnt[a[i]]++; } sort(a,a+n); long long ans=1; if (a[0]!=a[1]&&a[1]!=a[2]) ans*=cnt[a[0]]*cnt[a[1]]*cnt[a[2]]; if (a[0]==a[1]&&a[1]!=a[2]) ans*=cnt[a[0]]*(cnt[a[0]]-1)*cnt[a[2]]/2; if (a[0]==a[1]&&a[1]==a[2]) ans*=cnt[a[0]]*(cnt[a[0]]-1)*(cnt[a[0]]-2)/6; if (a[0]!=a[1]&&a[1]==a[2]) ans*=cnt[a[0]]*cnt[a[1]]*(cnt[a[1]]-1)/2; cout<<ans<<endl; }
一定要用long long , 一定要注意数据范围!!!注意数据范围!!!

浙公网安备 33010602011771号