列表

详情


PDD12. 两两配对差值最小

描述

给定一个长度为偶数的数组arr,将该数组中的数字两两配对并求和,在这些和中选出最大和最小值,请问该如何两两配对,才能让最大值和最小值的差值最小?

输入描述

一共2行输入。
第一行为一个整数n,2<=n<=10000, 第二行为n个数,,组成arr数组,0<=arr[i]<=100。

输出描述

输出最小的差值。

示例1

输入:

4
2 6 4 3

输出:

1

示例2

输入:

6
11 4 3 5 7 1

输出:

3

原站题解

C 解法, 执行用时: 2ms, 内存消耗: 344KB, 提交时间: 2021-10-07

#include<stdio.h>

void quicksort(int *a, int begin, int end) {
    if(begin >= end)
        return;
    int i = begin, j = end;
    int mid = a[i];
    while(i < j) {
        while(i < j && a[j] > mid)
            j--;
        if(i < j)
            a[i++] = a[j];
        while(i < j && a[i] < mid)
            i++;
        if(i < j)
            a[j--] = a[i];
    }
    a[i] = mid;
    quicksort(a,begin,i-1);
    quicksort(a,i+1,end);
}

int main() {
    int n;
    scanf("%d",&n);
    int arr[n];
    for(int i = 0; i < n; i++) {
        scanf("%d",&arr[i]);
    }
    quicksort(arr,0,n-1);
    int max = 0,min = 200;
    for(int i = 0; i <= (n-1)/2; i++) {
        int temp = arr[i] + arr[n - i - 1];
        if(temp > max) {
            max = temp;
        }
        if(temp < min) {
            min = temp;
        }
    }
    printf("%d",max-min);
}

C++ 解法, 执行用时: 2ms, 内存消耗: 376KB, 提交时间: 2020-08-02

#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
#include <map>
#include <unordered_map>
#include <string>
#include <cmath>

using namespace std;

//int main(){
//    int N, K;
//    string str;
//    cin >> N >> K;
//    cin >> str;
//
//    int l=0, r;
//    vector<int> count(10, 0);
//    for(auto c : str) count[c - '0'] += 1;
//
//    int min_val = 10000000;
//
//    for(int i=0; i<10; i++){
//        int temp_num = count[i];
//        string ret = str;
//        if(temp_num >= K){
//            cout << 0 << endl;
//            cout << ret;
//        }
//
//        int temp_val = 0;
//        for(int j=1; j<10; j++){
//            if(i+j < 10) temp_num += count[j];
//            if(temp_num >= K){
//
//            }
//        }
//    }
//}


int main(){
    int N;
    cin >> N;
    vector<int> array(N);
    for(int i=0; i<N; i++) cin >> array[i];
    sort(array.begin(), array.end());
    int max_val = -10000000, min_val = 100000000;
    int l = 0, r = array.size()-1;
    while(l < r){
        int temp = array[l++] + array[r--];
        max_val = max(max_val, temp);
        min_val = min(min_val, temp);
    }
    cout << max_val - min_val;
}

C 解法, 执行用时: 2ms, 内存消耗: 376KB, 提交时间: 2020-03-07

#include <stdio.h>
#include<stdlib.h>
void Merge(int *num, int start, int mid, int end);
void Merge_Sort(int *num, int start, int end)
{
	if (start >= end)
	{
		return;
	}
	int mid = start + (end - start) / 2;
	Merge_Sort(num, start, mid);
	Merge_Sort(num, mid + 1, end);
	Merge(num, start, mid, end); 
}

void Merge(int *num, int start, int mid, int end)
{
	int *temp = (int *)malloc((end-start+1) * sizeof(int));
	int i = start;
	int j = mid + 1;
	int k=0;
	while (i <= mid && j <= end)
	{
		if (num[i] <= num[j])
		{
			temp[k++] = num[i++];
		} else {
			temp[k++] = num[j++];
		}	
	}
	while (i <= mid)
	{
		temp[k++] = num[i++]; 
	}
	while( j <= end)
	{
		temp[k++] = num[j++];
	}
	for (i=0; i < k; i++)
	{
		num[start + i] = temp[i];
	}
	free(temp);
}
int main()
{
	int n;
	int max = 0;
	int min = 99999999;
	int a[10001];
	int b[5000];
	scanf("%d",&n);
	for (int i = 0; i < n; i++)
	{
		scanf("%d",&a[i]);
	}
	Merge_Sort(a,0,n-1);
	/*
	for (int i = 0; i < n; i++)
	{
		printf("%d  ",a[i]);
	}
	*/
	for (int i=0,j=n-1; i <= j;i++, j--)
	{
		b[i]=a[i]+a[j];
	}
	/*
	for (int i = 0; i < n/2; i++)
	{
		printf("%d  ",b[i]);
	}
	*/
	for (int i=0; i < n/2; i++)
	{
		if (b[i] > max)
		{
			max =b[i];
		} 
		if (b[i] < min)
		{
			min =b[i];
		}
	}
	//printf("max = %d, min = %d",max, min);
	printf("%d",max-min);
}

C 解法, 执行用时: 2ms, 内存消耗: 384KB, 提交时间: 2021-09-21

#include <stdio.h>
#include <limits.h>

//index要调整的结点  n是总共结点数 
void reHeap(int arr[],int index,int n){
	int child = 2*index+1;
	int key = arr[index];//需要调整的结点的元素 
	while(child<n){//叶子结点存在 
		if(child+1<n && arr[child] < arr[child+1]){//右孩子存在且比左孩子大 
			++child;	
		} 
		//child记录孩子中更大的那个结点下标
		if(key<arr[child]){
			arr[index] = arr[child];//把孩子的元素放在父结点处 
			index = child;
			child = 2*index+1;
		}else{
			break;
		}
	} 
	arr[index] = key;
} 
//时间复杂度是O(nlogn)  空间复杂度O(1)  不稳定 
void heapSort(int arr[],int n){
	//把完全二叉树调整成大根堆
	int i;
	for(i=n/2;i>=0;--i)//第一个非叶子结点 n/2   从下往上调整 
		reHeap(arr,i,n); 
	for(i=0;i<n-1;i++){//循环进行n-1次
		//arr[0]和arr[n-1-i]最后一个元素交换 
		int tmp = arr[0];
		arr[0] = arr[n-1-i];
		arr[n-1-i] = tmp;
		//不考虑最后一个元素的基础上,重新调整成大根堆  只需要调整0结点 
		reHeap(arr,0,n-1-i);
	}
}

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        int index=0;
        int arr[n];
        while(index<n)
            scanf("%d",&arr[index++]);
        heapSort(arr,index);
        int i=0,j=index-1;
        int max=INT_MIN,min=INT_MAX;
        while(i<j)
        {
            if(arr[i]+arr[j]>max)
                max=arr[i]+arr[j];
            if(arr[i]+arr[j]<min)
                min=arr[i]+arr[j];
            i++;
            j--;
        }
        printf("%d\n",max-min);
    }
}

C++ 解法, 执行用时: 2ms, 内存消耗: 396KB, 提交时间: 2021-09-11

#include<iostream>
#include<vector>
#include<cmath>
#include<algorithm>

using namespace std;

int main(){
    int n;
    cin>>n;
    vector<int> num(n);
    for(int i=0;i<n;i++){
        cin>>num[i];
    }
    sort(num.begin(),num.end());
    int maxi=INT32_MIN;
    int mini=INT32_MAX;
    for(int i=0;i<n-1;i+=2){
        maxi=max(maxi,num[i]+num[n-i-1]);
        mini=min(mini,num[i]+num[n-i-1]);
    }
    cout<<maxi-mini;
    return 0;
}

上一题