输入包含多组测试数据。
对于每组测试数据:
N - 本组测试数据有n个数
a1,a2...an - 需要计算的数据
保证:
1<=N<=100000,0<=ai<=INT_MAX.
对于每组数据,输出两个数,第一个数表示差最小的对数,第二个数表示差最大的对数。
6 45 12 45 32 5 6
1 2
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
void result(vector<int>&a, int n);
int main()
{
int num;
while (cin >> num)
{
int temp;
vector<int>data;
for (int i = 0; i < num; ++i)
{
cin >> temp;
data.push_back(temp);
}
result(data, num);
}
return 0;
}
void result(vector<int>&a, int n)
{
if (n > 1)
{
sort(a.begin(), a.end());
int m1 = 1;
int m2 = 1;
for (int i = 0; i < n-1; ++i)
{
if (a[i + 1] != a[i])
break;
++m1;
}
for (int i = n - 1; i > 0; --i)
{
if (a[i - 1] != a[i])
break;
++m2;
}
int max = m1*m2;
int min_temp = a[1] - a[0];
int min = 0;
for (int i = 2; i < n; ++i)
if (a[i] - a[i - 1] < min_temp)
min_temp = a[i] - a[i - 1];
if (min_temp == 0)
{
for (int i = 1; i < n; ++i)
{
int j = i - 1;
while (j >= 0 && a[j] == a[i])
{
++min;
--j;
}
}
}
else
{
for (int i = 1; i < n; ++i)
if (a[i] - a[i - 1] == min_temp)
++min;
}
cout << min << ' ' << max << endl;
}
}
思路:
注意:千万不要忽略重复元素的情况!比如:3 3 3 3,最大值对是6对!而不是3对,更不是12对!
所用数据结构: vector
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
int num,i,j;
while(cin>>num)//读入元素的总个数
{
if(num<2)
{
cout<<0<<" "<<0<<endl;
continue;
}
vector<int> arr;//arr不要声明为全局变量,不然全部测试数据都被存入了arr
int length=num;
int temp;
while(num--)//不能写成while(cin>>temp),不然,全部测试数据都被一次性存入了arr
{
cin>>temp;
arr.push_back(temp);
}
sort(arr.begin(),arr.end());//C++排序函数:对[begin,end)内所有元素排序
//求最小值minVal
int minVal=arr[1]-arr[0];
for(i=1;i<length-1;++i)
{
int cur=arr[i+1]-arr[i];
if(cur<minVal)
minVal=cur;
}
//求最小值的个数minCount
int minCount=0;
if(minVal==0)//arr中有相等元素时
{
for(i=0;i<length-1;++i)
{
for(j=i+1;j<length;++j)
{
if(arr[i]==arr[j])
++minCount;
}
}
}
else//arr中无元素相等时
{
for(i=0;i<length-1;++i)
{
int cur=arr[i+1]-arr[i];
if(cur==minVal)
{
++minCount;
}
}
}
//求最大值maxVal
int maxVal=arr[length-1]-arr[0];
//求最大值的个数maxCount
int maxCount=0;
if(maxVal==0)//全部元素都相等,利用组合原理
{
maxCount=length*(length-1)/2;
}
else//有不同的元素,最大值的个数=最小的个数*最大的个数
{
int smallCount=0,bigCount=0;
for(i=0;i<length;++i)
{
if(arr[i]==arr[0])
++smallCount;
else if(arr[i]==arr[length-1])
++bigCount;
}
maxCount=smallCount*bigCount;
}
cout<<minCount<<" "<<maxCount<<endl;
}
return 0;
}
#include <iostream>
#include <map>
#include <utility>
using namespace std;
// 用一个map来存储输入的数,当存在相同的数时不插入新的数,而是将计数值+1
int main()
{
int num;
while(cin>>num)
{
map<int,int> myMap;
bool flag = false;
for(int i = 0; i < num ; i++)
{
int k ;
cin>>k;
map<int,int>::iterator ite;
ite = myMap.find(k);
if(ite != myMap.end())
{ (*ite).second++;flag = true;}
else
{
myMap.insert(make_pair(k,1));
}
} // end of for 读取输入的数据
map<int,int>::iterator ite = myMap.begin();
int min =0;
int minv = -1;
if(flag) //如果存在相同的数
{
for( ; ite!= myMap.end(); ite++)
{
if((*ite).second > 1)
min += ((*ite).second * ((*ite).second -1 ))/2;
} //最小差元组对数等于所有相等的数构成的元组对
}
else
{
for( map<int,int>::iterator ite2 = (++myMap.begin()); (ite2)!= myMap.end(); ite2++,ite++ )
{
int k = (*(ite2)).first - (*(ite)).first;
if( minv ==-1 || k < minv )
{ min = (*ite).second * (*ite2).second ;
minv = k; }
else if(minv == k)
{
min+= (*ite).second * (*ite2).second;
}
} // end of for 求不存在相等的值时的最小差的元组对数
}// 最小对的个数
int max;
if( (*myMap.rbegin()).first != (*myMap.begin()).first)
max = (*myMap.rbegin()).second * (*myMap.begin()).second;
else
max = (*myMap.rbegin()).second *((*myMap.rbegin()).second-1)/2;//最大差的对数
cout<< min<<" "<<max<<endl;
}
}
import java.util.Arrays;
import java.util.Scanner;
public class Jd_NumAbs {
private static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
while (scanner.hasNext()) {
int num = scanner.nextInt();
int[] nums = new int[num];
for (int i = 0; i < num; i++) {
nums[i] = scanner.nextInt();
}
// getMinMaxAbsNums(nums, num);
fun2(nums, num);
}
}
public static void getMinMaxAbsNums(int[] nums, int len) {
int minNum = 0, maxNum = 0;
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
for (int i = 0; i < len - 1; i++) {// 时间复杂度n^2
for (int j = i + 1; j < len - 1; j++) {
int abs = Math.abs(nums[i] - nums[j]);
if (abs < min) {
minNum = 1;
min = abs;
} else if (min == abs) {
minNum++;
} else if (abs > max) {
max = abs;
maxNum = 1;
} else if (max == abs) {
maxNum++;
}
}
}
System.out.println(minNum + " " + maxNum);
}
public static void fun2(int[] nums, int len) {
Arrays.sort(nums);// 时间复杂度nlogn
int maxCount = 0;
int minNum = 1, maxNum = 1;// 数组中最小和最大元素的个数
int i = 1;
while (i < len && nums[i - 1] == nums[i]) {
minNum++;
i++;
}
i = len - 2;
while (i >= 0 && nums[i] == nums[i + 1]) {
maxNum++;
i--;
}
if (nums[0] == nums[len - 1]) {
maxCount = len * (len - 1) / 2;
} else {
maxCount = minNum * maxNum;
}
for (int j = 1; j < len; j++) {
nums[j - 1] = Math.abs(nums[j] - nums[j - 1]);
}
int minValue = Integer.MAX_VALUE;
int minCount = 0;
for (int j = 0; j < nums.length; j++) {//初次统计minValue
if (nums[j] < minValue) {
minCount = 1;
minValue=nums[j];
} else if (nums[j] == minValue) {
minCount++;
}
}
if(minValue==0){//如果最小差值为0,统计0的区间个数
minCount=0;
int tempMinCount=0;
for (int j = 0; j < len-1; j++) {
if (nums[j]==0) {
tempMinCount++;
}else {
minCount+=tempMinCount*(tempMinCount+1)/2;
tempMinCount=0;
}
}
minCount+=tempMinCount*(tempMinCount+1)/2;
}
System.out.println(minCount + " " + maxCount);
}
}
import sys
for line in sys.stdin:
temp = [int(i) for i in line.split()]
if len(temp) == 1:
# 把N跳过
continue
temp.sort()
Dict = {}
for i in temp:
if i in Dict:
Dict[i] += 1
else:
Dict[i] = 1
res = 0
for k in Dict.keys():
if Dict[k] >= 2:
temp2 = [i for i in range(Dict[k])]
res += sum(temp2)
if res == 0:
# 没重复的情况,比如[1,2,3,9]这种
temp3 = []
for j in range(len(temp)-1):
temp3.append(temp[j+1] - temp[j])
temp3.sort()
# print()会换行,算例通不过,加了end就不会换行
print(temp3.count(temp3[0]), end=" ")
else:
print(res, end=" ")
num_max, num_min = Dict[temp[-1]], Dict[temp[0]]
print(num_max*num_min) 我用python3,各位一定要注意print()会直接换行,算例通不过
import java.util.*;
public class Main {
public static void main(String[] args) {
///输入处理
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
int n = sc.nextInt();
int[] num = new int[n];
for (int i = 0; i < n; i++) {
num[i] = sc.nextInt();
}
//先对数组排序,方便找最大最小,也方便求每个数字的次数
Arrays.sort(num);
//如果所有的数字都相等,想想为什么要单独判断?
if (num[n - 1] == num[0]) {
int res = n * (n - 1) / 2;
System.out.println(res + " " + res);
continue; //continue返回,因为在while循环里面
//统计次数
}
//注意,此处用TreeMap,它能自动排序,因为后面
//求最大值时,需要用到
Map<Integer, Integer> map = new TreeMap<>();
for (int val : num) {
if (map.containsKey(val)) {
map.put(val, map.get(val) + 1);
} else {
map.put(val, 1);
}
}
//求最小值
int minCnt = 0;
if (map.size() == n) { //没有重复数字
int minNum = Math.abs(num[0] - num[1]);
for (int i = 1; i < n; i++) { //当需要数组中相邻的数字比较时,尤其注意数组越界的情况
int tmp = Math.abs(num[i] - num[i-1]);
if (tmp == minNum) {
minCnt ++;
} else if (tmp < minNum) {
minNum = tmp;
minCnt = 1;
}
}
} else {
for (int val : map.keySet()) {
int value = map.get(val);
if (value > 1) {
minCnt += (value * (value - 1)) / 2;
}
}
}
//求最大值
List<Integer> list = new ArrayList<>(map.keySet());
int max = map.get(list.get(0)) * map.get(list.get(list.size() - 1));
System.out.println(minCnt + " " + max);
}
}
}
import sys def main(): k = 0 for line in sys.stdin: k = 1 - k if (k == 0): li = [int(i) for i in line.strip().split()] m = len(li) li.sort() small, big = li[0], li[m-1] smallnum, bignum, ansbig, anssmall, mincha, mincount = 1, 1, 0, 0, -1, 0 # answer big while (li[smallnum] == small): smallnum += 1 while (li[m-1-bignum] == big): bignum += 1 ansbig = smallnum * bignum #answer small for i in range(m-1): if (li[i+1] - li[i] < mincha or mincha < 0): mincha = li[i+1] - li[i] mincount = 1 elif (li[i+1] - li[i] == mincha): mincount += 1 if (mincha > 0): anssmall = mincount else: p = 0 for i in range(m-1): if (li[i+1] == li[i]): p += 1 else: if (p > 0): anssmall += p * (p + 1) / 2 p = 0 anssmall += p * (p + 1) / 2 print str(anssmall) + " " + str(ansbig) main()
#include <stdio.h>
#include <algorithm>
int main() {
int n, a[100000];
while(~scanf("%d", &n)) {
int t = n;
while(t--)
scanf("%d", a + t);
std::sort(a, a + n);
int j = n - 2, nMin = 1, nMax = 1;
int nMaxDiff = 0, nMinDiff = 0, minDiff = 0x7fffffff;
while(nMin < n && a[nMin - 1] == a[nMin])
nMin++;
while(j >= 0 && a[j] == a[j + 1]) {
j--;
nMax++;
}
nMaxDiff = nMin * nMax;
//find minDiff and add nMinDiff
for(int i = 1; i < n; i++) {
int d = a[i] - a[i - 1];
if(d < minDiff) {
minDiff = d;
nMinDiff = 0;
}
if(minDiff == 0)
break;
nMinDiff += (d == minDiff);
}
//minDiff = 0, find equal numbers and add nMinDiff
if(minDiff == 0) {
int m = 1;
for(int i = 1; i < n; i++) {
if(a[i] == a[i - 1]) {
m++;
} else if(m > 1) {
nMinDiff += m * (m - 1)/2;
m = 1;
}
}
nMinDiff += (m > 1) ? m * (m - 1)/2 : 0;
}
printf("%d %d\n", nMinDiff, nMaxDiff);
}
return 0;
}
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
int n=sc.nextInt();
int[]num=new int[n];
for(int i=0;i<n;i++)
num[i]=sc.nextInt();
Arrays.sort(num);
int min=Integer.MAX_VALUE;
int countmin=0;
for(int i=1;i<n;i++){
if(min>(num[i]-num[i-1])){
countmin=0;
min=num[i]-num[i-1];
if (min==0)
break;
}
if((num[i]-num[i-1])==min)
countmin++;
}
if(min==0){
int min_num=1;
for(int i=1;i<n;i++){
if(num[i]==num[i-1]){
min_num++;
}
else if(min_num!=1){
countmin+=min_num*(min_num-1)/2;
min_num=1;
}
}
}
int countmax=0;
int num1=0;
int num2=0;
int i=0;
while(i<n){
if(num[i]==num[0]){
num1++;
i++;}
else
break;
}
int j=n-1;
while(j>=0){
if(num[j]==num[n-1]){
num2++;
j--;}
else
break;
}
countmax=num1*num2;
System.out.println(countmin+" "+countmax);
}
}
}
测试用例只通过10%,最小对数有问题,而且是普通非相等情况出问题,不知怎么回事。
key存储元素值,value存储元素出现次数,map自动按照key升序排列 abs(x - y) ,一定是非负数,因此 (nums[i], nums[j]) 与 (nums[j],nums[i])是一种情况,即「组合数 」 #include <bits/stdc++.h>
using namespace std;
int main() {
int n, x;
while (cin >> n) {
map<int, int> mp; // 自动按照键排序
while (n--) cin >> x, ++mp[x];
int maxDiffCnt = 0, minDiffCnt = 0, minDiff = INT_MAX, pre = -1;
if (mp.size() == 1) { // map中只有一个元素的情况(个数为1 或 所有元素均相同)
maxDiffCnt = mp.begin() -> second * (mp.begin() -> second - 1) / 2;
printf("%d %d\n", maxDiffCnt, maxDiffCnt);
continue; // 本次遍历结束
}
// 以下为map中含有2个及以上元素的情况
maxDiffCnt = mp.begin() -> second * prev(mp.end()) -> second;
for (auto &[num, cnt] : mp) {
if (cnt > 1) { // 含有多个值相同的元素,则最大差值为0
if (minDiff > 0) { minDiff = 0; minDiffCnt = 0; }
minDiffCnt += cnt * (cnt - 1) / 2; // 选择问题,cnt中选两个
} else { // 当前元素只有一个
if (pre == -1);
else if (num - pre == minDiff) { // 差值与之前差值相同
++minDiffCnt;
} else if (num - pre < minDiff) { // 差值比之前差值小,更新minDiff
minDiff = num - pre;
minDiffCnt = 1;
}
}
pre = num;
}
printf("%d %d\n", minDiffCnt, maxDiffCnt);
}
return 0;
}
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line;
while((line = br.readLine()) != null) {
int n = Integer.parseInt(line.trim());
String[] strArr = br.readLine().trim().split(" ");
int[] arr = new int[n];
// 统计每个数的出现次数
HashMap<Integer, Integer> counter = new HashMap<>();
int min = Integer.MAX_VALUE;
for(int i = 0; i < n; i++){
arr[i] = Integer.parseInt(strArr[i]);
if(counter.containsKey(arr[i])){
counter.put(arr[i], counter.get(arr[i]) + 1);
min = 0;
}else
counter.put(arr[i], 1);
}
Arrays.sort(arr);
if(arr[n - 1] == arr[0]){
// 最值相等,二元组数均为数组长度n的组合数
System.out.println(n*(n - 1) / 2 + " " + n*(n - 1) / 2);
}else{
// 求最小差二元组数
int minCount = 0;
if(min == 0){
// 此时最小差值为0,二元组个数为每个重复数字出现次数的组合数之和
for(int num: counter.keySet())
if(counter.get(num) > 1) minCount += counter.get(num)*(counter.get(num) - 1) / 2;
}else{
min = Math.abs(arr[1] - arr[0]);
for(int i = 2; i < n; i++){
int temp = Math.abs(arr[i] - arr[i - 1]);
if(temp == min)
minCount++;
else if(temp < min){
min = temp;
minCount = 1;
}
}
}
// 求最大差二元组数(最大和最小数组合,即最大数的个数*最小数的个数)
int maxCount = counter.get(arr[0]) * counter.get(arr[n - 1]);
System.out.println(minCount + " " + maxCount);
}
}
}
} clude<iostream>
#include<vector>
(721)#include<algorithm>
using namespace std;
int main(){
int n,t;
while(cin>>n){
vector<int> nums(n);
for(int i=0;i<n;i++){
cin>>nums[i];
}
sort(nums.begin(),nums.end());
int mindis=nums[1]-nums[0];//初始值
int maxdis=nums[n-1]-nums[0];//确定值
int maxp=0,minp=0,tmp;
for(int i=0;i<n-1;i++){
mindis=min(nums[i+1]-nums[i],mindis);//找最小差值(出现在相邻数间)
}
for(int i=0;i<n;i++){
for(int j=n-1;j>i;j--){
tmp=nums[j]-nums[i];
if(tmp==maxdis) maxp++;
if(tmp==mindis) minp++;
}
}
cout<<minp<<" " <<maxp<<endl;
}
return 0;
} import sys
def qSort(lst,start,end):
"""快速排序"""
if start >= end:
return
i = start; j = end
r = lst[i] # 将lst[i]选做枢轴元素
while i < j:
while i < j and lst[j] >= r:
j -= 1
if i < j:
lst[i] = lst[j]
i += 1
while i < j and lst[i] <= r:
i += 1
if i < j:
lst[j] = lst[i]
j -= 1
lst[i] = r
qSort(lst,start,i-1)
qSort(lst,i+1,end)
def getMaxPair(lst,n):
# 数组中所有数字都相等,那么差最大的对就是它们两两组合
if lst[0] == lst[n-1]:
return n*(n-1)//2
# 找出最小的数有多少个
for i in range(1,n-1):
if lst[i] != lst[0]:
break
# 找出最大的数有多少个
for j in range(1,n-1):
if lst[n-1-j] != lst[n-1]:
break
return i*j
def getMinPair(lst,n):
# 数组中所有数字都相等,那么差最小的对就是它们两两组合
if lst[0] == lst[n-1]:
return n*(n-1)//2
mincount = 0
mindiff = lst[1] - lst[0]
count = 1
for i in range(1,n-1):
# 差为0时对数的计算方法是不一样的,所以跳出
if mindiff == 0:
break
if lst[i+1]-lst[i] == mindiff:
count += 1
elif lst[i+1]-lst[i] < mindiff:
mindiff = lst[i+1]-lst[i]
count = 1
if mindiff == 0:
for i in range(0,n-1):
# 找出差为0的段的起始点
if lst[i+1]-lst[i] == 0 and (i==0 or lst[i]-lst[i-1]>0):
start = i
# 找出差为0的段的终点
if lst[i+1]-lst[i] == 0 and (i+1==n-1 or lst[i+2]-lst[i+1]>0):
end = i+1
equalnum = end-start+1
# 可能存在多个差为0的子序列,故应分段计算,再把它们相加
mincount = mincount + equalnum*(equalnum-1)//2
return mincount
else:
return count
if __name__ == '__main__':
while True:
num = sys.stdin.readline().strip()
if not num:
break
n = int(num)
line = sys.stdin.readline().strip()
if not line:
break # 这一步不能少,否则退出时会报错
strlst = line.split(' ')
lst = list(map(int,strlst))
qSort(lst,0,n-1)
print(str(getMinPair(lst,n))+' '+str(getMaxPair(lst,n))) import sys
def MaxAndMinPair(s):
if len(s) <= 1:
return 0
s.sort(reverse=True)
if s[0] == s[-1]:
minPair = maxPair = int(len(s) * (len(s) - 1) / 2)
print(str(minPair)+' '+str(maxPair))
else:
minGap = s[0] - s[-1]
minPair = 1
for i in range(len(s)-1):
if s[i] - s[i + 1] < minGap:
minGap = s[i] - s[i + 1]
if minGap == 0:
break
minPair = 1
continue
if s[i] - s[i + 1] == minGap:
minPair += 1
if minGap == 0:
minPair = 0
elementDic = {}
for i in range(len(s)):
if s[i] not in elementDic:
elementDic[s[i]] = 1
else:
elementDic[s[i]] += 1
for key in elementDic:
num = elementDic[key]
minPair += num*(num-1)/2
# to find the max gap pair num
# 2 1 1 1
maxNum = 1
minNum = 1
for i in range(len(s)-1):
if s[i] == s[i+1]:
maxNum += 1
else:
break
for i in range(len(s)-1):
if s[len(s)-1-i] == s[len(s)-2-i]:
minNum += 1
else:
break
print(str(int(minPair)) + ' ' + str(maxNum * minNum))
if __name__ == '__main__':
k = 0
for line in sys.stdin:
k = 1 - k
if (k == 0):
data = [int(i) for i in line.strip().split()]
MaxAndMinPair(data) 贴一个排序后二分的代码,做的时候clang编译器有问题,给min_cha赋初值(long long)1e20最后一个测试数据会出错,本地g++就没问题,现在给min_cha赋值2*30就AC了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+5;
ll A[maxn];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n = 0;
while(cin >> n){
for(int i=0;i<n;i++){
cin >> A[i];
}
sort(A,A+n);
ll min_cha = 1<<30;
for(int i=1;i<n;i++){
min_cha = min(min_cha,A[i]-A[i-1]);
}
ll ans1 = 0;
for(int i=0;i<n-1;i++){
int t = upper_bound(A,A+n,A[i]+min_cha)-A;
ans1 += (t-i-1);
}
ll max_cha = A[n-1] - A[0];
ll ans2 = 0;
for(int i=0;i<n;i++){
int t = lower_bound(A+i,A+n,A[i]+max_cha)-A;
ans2 += (n-t);
}
cout << ans1 << " " << ans2 << endl;
}
return 0;
}