题目描述:
小Q今天在上厕所时想到了这个问题:有n个数,两两组成二元组,相差最小的有多少对呢?相差最大呢?
输入描述:
输入包含多组测试数据。
对于每组测试数据:
N - 本组测试数据有n个数
a1,a2...an - 需要计算的数据
保证:
1<=N<=100000,0<=ai<=INT_MAX.输出描述:
对于每组数据,输出两个数,第一个数表示差最小的对数,第二个数表示差最大的对数。
示例1
输入
6 45 12 45 32 5 6输出
1 2
这一题乍以看很懵圈。
我是暴力解的,有点乱哈,先梳理一下思路。
特殊情况:
数组内是否有相同的数字:
如果有:那么最小值一定是0,我们要找出差值0的个数,即为最小值,也就是说要找出数组内有多少个相同的数字,假设最小值是1,在数组内仅有3个,那么差值为0的个数为:
num = (3-1)*3/2 = 3 对;
所以我们要找出数组内所有数字相同的组,并找出来这一组有多少个,利用公式 (n-1)*n/2,依次累加。即为最小值的对数。
最大值就是最小值的个数*最大值的个数,通过一次遍历即可求得。
如果没有相同的
那么最大值的对数只有一对,就是最大值减去最小值。但最小值的对数,我们要通过做遍历的手段来获得,获得之后还要再遍历一次,才能获得对数。
如果数组内的数据都相同
比如 1 1 1 1 1,那么最大值和最小值的对数都是一样的,即为最小值的对数。
代码如下:
//有趣的数字
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int st[1000000];
int main(){
int n;
while(cin>>n){
int maxnum = 0;
int minnum = 2147483647;//可以用INT_MAX
for(int i=0;i<n;i++){
cin>>st[i];
if(st[i]>maxnum){
maxnum = st[i]; //在输入数据的时候就找出来最大值和最小值
}
if(st[i]<minnum){
minnum = st[i];
}
}
sort(st,st+n); //排序
int sumSame = 0; //相同数字的个数(求最小值)
int minN = 0,maxN = 0; //最大值和最小值分别各有多少个
int pos = 1; //计数器
for(int i=0;i<n;i++){
if(st[i]==minnum){ //统计最大值 个数
minN++;
}
if(st[i]==maxnum){ //统计最小值个数
maxN++;
}
if(i!=0&&st[i-1]==st[i]){ //判断相同数字的个数
pos++;
}else{
if(pos>=2){ //大于等于2时才可以去做累加
sumSame+=pos*(pos-1)/2;
}
pos = 1; //累加完后初始化
}
}
if(pos!=1){ //如果当前pos还有数字,加上去
sumSame+=pos*(pos-1)/2;
}
if(sumSame==0){ //数组内没有一个相同的
int temp = 2147483647;
for(int k=1;k<n;k++){
if(st[k]-st[k-1]<temp){ //找出最小差值
temp = st[k] - st[k-1];
}
}
for(int k=1;k<n;k++){
if(st[k]-st[k-1]==temp){ //找出最小差值的个数
sumSame++;
}
}
}
if(minN==n){ //全相同
maxN = 1;
minN = sumSame;
}
cout<<sumSame<<" "<<minN*maxN<<endl;
}
}