【备战秋招】每日一题:2023.08.23-得物-第一题-开幕式演练

为了更好的阅读体检,可以查看我的算法学习网
在线评测链接:P1481

题目描述

导演在组织进行大远会开幕式的排练,其中一个环节是需要参演人员围成一个环形。演出人赞站成了一圈、出于美观度的考虑,导演不希望某一个演员身边的其他人比他低太多或高太多。

现在输出 s s s个参演人员的身高、问在他们站成一圈时,相邻演员的身高差的最大值至少是多少,请你帮忙计算。

输入描述

输入包恬两行,第一行有 1 1 1个正整数,代表人数 n n n

第二行有个 a a a空格隔开的正整数 h h h,表示第 i i i个演员的身高

数据保证 2 ≤ n ≤ 1 0 5 , 1 ≤ h ≤ 1 0 9 2 \leq n \leq 10^5,1 \leq h \leq 10^9 2n105,1h109

输出描述

输出包括一个正整数,表示答案

样例

输入

5
2 1 1 3 2

输出

1

提示

样例输入 2 2 2

2 2 2

10 10 10 20 20 20

样例输入 2 2 2

10 10 10

样例1中排为 1 , 2 , 3 , 2 , 1 1,2,3,2,1 12321即可。样例 2 2 2中排为 10 , 20 10,20 1020即可。

1.开幕排练

题目描述

导演在组织进行大远会开幕式的排练,其中一个环节是需要参演人员围成一个环形。演出人赞站成了一圈、出于美观度的考虑,导演不希望某一个演员身边的其他人比他低太多或高太多。

现在输出 s s s个参演人员的身高、问在他们站成一圈时,相邻演员的身高差的最大值至少是多少,请你帮忙计算。

输入描述

输入包恬两行,第一行有 1 1 1个正整数,代表人数 n n n
第二行有个 a a a空格隔开的正整数 h h h,表示第 i i i个演员的身高
数据保证 2 ≤ n ≤ 1 0 5 , 1 ≤ h ≤ 1 0 9 2 \leq n \leq 10^5,1 \leq h \leq 10^9 2n105,1h109

输出描述

输出包括一个正整数,表示答案

样例

输入

5
2 1 1 3 2

输出

1

样例输入2

2

10 20

样例输入2

10

提示

样例1中排为 1 , 2 , 3 , 2 , 1 1,2,3,2,1 12321即可。样例 2 2 2中排为 10 , 20 10,20 1020即可。

解题思路

这一题应该算是今晚最难的题了。
考虑环形这个特殊性质,这里不难想象构造一个对称的序列,相对来说答案是更优的。
观察提示中的序列,那么可以想象到一种构造方法:
即序列排序后,如果n为奇数,那么先放入一个最大值,若n为偶数则不做操作。接下来每次往序列的两端插入最大值和次大值(分别插入在左右两边),这样就可以保证序列的对称性。
证明的话,需要考虑一个样例,如2 4 3 9 8 4,假设直接这样来计算,那么很显然多个波浪(即先递增后递减的区间片段)是不优的。最简单的,我们要构造先递增后递减的序列,并且使得递增序列的长度和递减长度的差值尽可能小(在本题中,两者相等)。
为了代码美观,这里cpp使用了STL中的双端队列。

Cpp代码

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

int main()
{
    ios::sync_with_stdio(false);
    int n;
    cin +/->> n;
    vector<int> a(n);
    for (int i = 0; i < n; i++)
        cin >> a[i];
    sort(a.begin(), a.end());
    deque<int> d;
    for (int i = n - 1; i >= 0; i--)
    {
        d.push_back(a[i--]);
        if (i >= 0)
            d.push_front(a[i]);
    }
    int ans = abs(d.front() - d.back());
    int head;
    for (int i = 1; i < n; i++)
    {
        head = d.front();
        d.pop_front();
        ans = max(ans, abs(head - d.front()));
    }
    cout << ans << endl;
}

java代码

import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = scanner.nextInt();
        }
        Arrays.sort(a);
        Deque<Integer> d = new ArrayDeque<>();
        for (int i = n - 1; i >= 0; i--) {
            d.addLast(a[i--]);
            if (i >= 0)
                d.addFirst(a[i]);
        }
        int ans = Math.abs(d.peekFirst() - d.peekLast());
        int head;
        for (int i = 1; i < n; i++) {
            head = d.pollFirst();
            ans = Math.max(ans, Math.abs(head - d.peekFirst()));
        }
        System.out.println(ans);
    }

}

python代码

if __name__ == "__main__":
    n = int(input())
    a = list(map(int, input().split()))
    a.sort()
    deque = []
    for i in range(n - 1, -1, -2):
        deque.append(a[i])
        if i >= 1:
            deque.insert(0, a[i - 1])
    ans = abs(deque[0] - deque[-1])
    for i in range(1, n):
        ans = max(ans, abs(deque[i] - deque[i - 1]))
    print(ans)

扩展

这题根据上面的构造,我们可以得到一个结论:答案必然出现在 a b s ( a i − a ( i + 2 ) ) abs(a_i - a_(i+2)) abs(aia(i+2))之中,通过观察可得。

Cpp代码

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

int main()
{
    ios::sync_with_stdio(false);
    int n;
    cin >> n;
    vector<int> a(n);
    for (int i = 0; i < n; i++)
        cin >> a[i];
    if (n == 2)
    {
        return abs(a[1] - a[0]);
    }
    sort(a.begin(), a.end());
    int ans = 0;
    for (int i = 2; i < n; i += 2)
        ans = max(ans, a[i] - a[i - 2]);
    for (int i = 3; i < n; i += 2)
        ans = max(ans, a[i] - a[i - 2]);
    cout<<ans<<endl;
}

java代码

import java.util.Arrays;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = scanner.nextInt();
        }
        if (n == 2)
        {
            System.out.println(Math.abs(a[1] - a[0]));
            return ;
        }
        Arrays.sort(a);
        int ans = 0;
        for (int i = 2; i < n; i += 2)
            ans = Math.max(ans, a[i] - a[i - 2]);
        for (int i = 3; i < n; i += 2)
            ans = Math.max(ans, a[i] - a[i - 2]);
        System.out.println(ans);
    }

}

python代码

if __name__ == "__main__":
    n = int(input())
    a = list(map(int, input().split()))
    if n==2:
        print(a[1]-a[0])
        exit()
    a.sort()
    ans = 0 
    for i in range(2,n,2):
        ans = max(ans,a[i]-a[i-2])
    for i in range(3,n,2):
        ans = max(ans,a[i]-a[i-2])
    print(ans)
    
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

塔子哥学算法

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值