版权声明:本人原创,未经许可,不得转载 https://blog.csdn.net/qq_42505741/article/details/84195809
题目:
Problem Description
小Z准备去爬山,在他的面前有N座山,每座山都有对应的高度。他想选择两座高度差最小的山进行攀爬。但由于好多山之间的高度差可能是相同的,所以他需要你告诉他高度差最小的两座山的高度差是多少以及有多少种不同的选取方式(选取山A、B和选取山B、A视为同一种选取方式)。
Input
输入一个T,代表数据的组数。(T<=10)
每组数据包含一个N,代表有多少座山。(2<=N<=100,000)
接下来一行包括N个数,分别表示每座山的高度x(1<=x<=1000,000,000)。
Output
扫描二维码关注公众号,回复:
4131327 查看本文章
对于每组测试样例,输出一行,包含两个整数,代表两座山最小的高度,以及有多少种不同的方式选取两座山。两个数之间用一个空格隔开,每个测试样例占一行。
Sample Input
2 5 1 2 5 4 3 4 3 3 3 10
Sample Output
1 4 0 3
Hint
测试样例包含2组样例 第一组样例有5座山,高度分别为1,2,5,4,3,所以高度差最小是1,有4种不同的选取方式, 分别为选取第一座山和第二座山、选取第二座山和第五座山、选取第四座山和第五座山、选取第三座山和第四座山。 第二组样例有4座山,高度分别为3,3,3,10,所以高度差最小是0,有3种不同的选取方式, 分别为选取第一座山和第二座山、选取第二座山和第三座山、选取第一座山和第三座山。
解题报告:这道题目先排序,然后遍历寻找最小的高度差,最大的坑点就是你需要处理一下当存在多段 相同数字的情况,因为同为高度差为0 可能会有多种情况,需要每种都去落实。
ac代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn=1e5+1000;
ll num[maxn];
int t,n;
ll min(ll a,ll b)
{
if(a<b)
return a;
return b;
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%lld",&num[i]);
}
sort(num+1,num+n+1);
ll minx=99999999;
num[0]=0;
for(int i=1;i<=n;i++)
{
minx=min(minx,num[i]-num[i-1]);
}
ll cnt=0,sum=0;
if(minx!=0)
{
for(int i=2;i<=n;i++)
{
if(num[i]==num[i-1]+minx)
cnt++;
}
printf("%lld %lld\n",minx,cnt);
}
else
{
cnt=1;
num[n+1]=0;
for(int i=1;i<=n;i++)
{
if(num[i]==num[i+1])
cnt++;
else
{
sum+=(cnt*(cnt-1)/2);
cnt=1;
}
}
// printf("%lld\n",cnt);
printf("%lld %lld\n",minx,sum);
}
}
return 0;
}