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;
}
View Code

 

一定要用long long , 一定要注意数据范围!!!注意数据范围!!!

posted @ 2017-12-19 10:08  人弱还是多做题  阅读(154)  评论(0)    收藏  举报