蓝桥杯pythonB组(小白逆袭之路)

本文介绍了一种计算机甲战队队员分组的最小战斗力差距的方法,通过将队员战斗力值排序并取相邻元素差值的最小值来确保分组的公平性,时间复杂度为O(nlogn)。
摘要由CSDN通过智能技术生成

最小化战斗力差距

问题描述

小蓝是机甲战队的队长,他手下共有n名队员,每名队员都有一个战斗力值 wi。现在他需要将这n名队友分成两组a和6,分组必须满足以下条件
。每个队友都属于a组或6组
。a组和6组都不为空
。战斗力差距最小。
战斗力差距的计算公式为max(a)min(6),其中max(a)表示a组中战斗力最大的,min(6)表示6组中战斗力最小的。
请你计算出可以得到的最小战斗力差距

import os

import sys

n=int(input())

w=list(map(int,input().split()))

a=float('inf') #zheng

w.sort()

for i in range(1,n):

    a=min(a,w[i]-w[i-1])

print(a)

 

解题思路

我们假设 \max(a)max(a) 为 xx,\min(b)min(b) 为 yy。求解 |x-y|∣x−y∣ 的最小值,本质上就是要使得 xx 和 yy 的相对距离最小。对于数组来说,将其排序后,相邻元素之间的相对距离一定是最小的,即答案为数组排序后所有相邻元素差值的最小值。

我们需要考虑这样排序后的构造是否是合法的,实际上可以构造一种满足条件的分组方法:假设对于排序后随意一组相邻的两个元素,左边的元素设为 ll,右边的元素为 rr,因为数组有序,所以 ll 左边的元素均不大于 ll,于是我们可以将 ll 左边的元素和 ll 视为 aa 组;同时 rr 右边的元素均不小于 yy,我们可以将 rr 右边的元素和 rr 视为 bb 组。这样就能够保证 ll 一定是 \max(a)max(a),rr 一定是 \min(b)min(b),即分组可行。

具体实现时,我们只需要将数组排序,然后在任意两个相邻元素的差值中取最小的即为答案。

时间复杂度为 O(n \log n)​O(nlogn)​。

AC_Code

  • C++
#include<bits/stdc++.h>
using namespace std;

int n;
int main()
{
    ios_base :: sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cin >> n;
    std::vector<int> a(n);
    for (int i = 0; i < n; ++i) cin >> a[i];
    sort(a.begin(), a.end());
    int ans = 1e9;
    for (int i = 1; i < n; ++i) ans = min(ans, a[i] - a[i - 1]);
    cout << ans << '\n';
    return 0;
}

  • Java
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; ++i) {
            a[i] = scan.nextInt();
        }
        Arrays.sort(a);
        int ans = Integer.MAX_VALUE;
        for (int i = 1; i < n; ++i) {
            ans = Math.min(ans, a[i] - a[i - 1]);
        }
        System.out.println(ans);
    }
}

  • Python
n = int(input())
a = list(map(int, input().split()))
a.sort()
ans = float('inf')
for i in range(1, n):
    ans = min(ans, a[i] - a[i - 1])
print(ans)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值