统计数组中差最小(或最大)的组合可能个数

来源:互联网 发布:xd mac 破解版 编辑:程序博客网 时间:2024/05/17 04:27

腾讯2017暑期实习生编程题第三题

小Q今天在上厕所时想到了这个问题:有n个数,两两组成二元组,差最小的有多少对呢?差最大呢?

输入例子:
6
45 12 45 32 5 6

输出例子:
1 2

思路:先排序,分一般情况和特殊情况,

特殊情况数组所有元素相同,差最小最大的组合个数都是C(n,2)

否则,差最大的组合个数 = 最小值个数MinNum * 最大值个数MaxNum

接下来求 ,差最小(minVal )的组合个数,

(1)若最小差为0,那么统计不同的重复元素的个数,我这里写的roo是后面出现相同元素的个数,所以roo=1的意思是后续数组只有1个与当前值相同的元素,就是C(2,2),通用公式是C(roo+1,2)

(2)最小差不为0,那么用 map 统计后续数组与当前值能构成最小差的元素的个数roo,直接加

//O(n+nlogn)#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <map>using namespace std;const int maxn = 100050;typedef long long int ll;int a[maxn];map<int,int> ma;int main(){   //  freopen("in.txt",stdin,"r");//  freopen("out.txt",stdout,"w");    int n;    while(scanf("%d",&n)!=EOF)    {        ma.clear();        for(int i=0;i<n;++i)scanf("%d",&a[i]);        sort(a,a+n);        if(a[0] == a[n-1]){            ll ans = n;            if(ans > 1)ans = ans * (ans-1)/2;            else ans = 0;// n == 1            printf("%lld %lld\n",ans,ans);        }        else{            ll MinNum = 0,MaxNum = 1,minVal = 2e11;            for(int i = 0;i < n - 1;++i)            {                if(a[i]==a[0])MinNum++;                if(a[i]==a[n-1])MaxNum++;                if(minVal > a[i+1]-a[i]) minVal = a[i+1] - a[i];                ma[a[i]]++;            }            ll MinAns = 0,roo = 0;            if(minVal == 0){                for(int i=0;i<n-1;++i)                {                    if(a[i]==a[i+1])roo++;                    else {                        if(roo>0){                            MinAns = MinAns + roo * (roo+1) / 2;                            roo = 0;                        }                                           }                }                if(roo>0){                    MinAns = MinAns + roo * (roo+1) / 2;                    roo = 0;                }                   }               else {                for(int i = 0;i < n;++i){                    roo = ma[a[i]+(int)minVal];                    if(roo > 0) MinAns += roo;                }               }                           printf("%lld %lld\n",MinAns,MinNum * MaxNum);        }           }    return 0;} 
0 0
原创粉丝点击