Codeforces Round #831 (Div. 1 + Div. 2) C. Bricks and Bags 解题报告

原题链接:

Problem - C - Codeforces

题目描述:

There are nn bricks numbered from 11 to nn. Brick ii has a weight of aiai.

Pak Chanek has 33 bags numbered from 11 to 33 that are initially empty. For each brick, Pak Chanek must put it into one of the bags. After this, each bag must contain at least one brick.

After Pak Chanek distributes the bricks, Bu Dengklek will take exactly one brick from each bag. Let wjwj be the weight of the brick Bu Dengklek takes from bag jj. The score is calculated as |w1−w2|+|w2−w3||w1−w2|+|w2−w3|, where |x||x| denotes the absolute value of xx.

It is known that Bu Dengklek will take the bricks in such a way that minimises the score. What is the maximum possible final score if Pak Chanek distributes the bricks optimally?

Input

Each test contains multiple test cases. The first line contains an integer tt (1≤t≤2⋅1041≤t≤2⋅104) — the number of test cases. The following lines contain the description of each test case.

The first line of each test case contains an integer nn (3≤n≤2⋅1053≤n≤2⋅105) — the number of bricks.

The second line of each test case contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤1091≤ai≤109) — the weights of the bricks.

It is guaranteed that the sum of nn over all test cases does not exceed 2⋅1052⋅105.

Output

For each test case, output a line containing an integer representing the maximum possible final score if Pak Chanek distributes the bricks optimally.

题目大意:

给你n个石头放入3个袋子,然后拿石头的人从3个袋子中依次拿出一个石头,value为 |w1−w2|+|w2−w3|

拿石头的人会让尽量让value最小,问你怎么分配这n块石头让value最大。

解题思路:

先对石子重量weg从小到大排序

考虑w1<w2<w3的清况,发现最大不过max-min。

当w1<w2且w3<w2时:

必然有a袋和c袋的最小大于b袋的最大,那么我们可以让a袋放最大的,b袋放前缀,c袋放剩下的,

那么这时a袋会取weg[n],b袋会取袋中最大的weg[i],c袋会取最小的weg[i+1],结果是weg[n]+weg[i+1]-2*weg[i]。

我们只要枚举b袋中取的那个就可以找到最大值。

当w1>w2且w3>w2时:

同理枚举b袋中取的哪一个,结果是2*weg[i]-weg[i-1]-weg[1]。

代码(CPP):

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define int long long
typedef unsigned long long ull;
const int maxn = 2e5 + 10;
const int INF = 0x3fffffff;
int n, a[maxn];

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout << fixed;
    cout.precision(18);

    int t;
    cin >> t;
    while(t--)
    {
        cin >> n;
        for (int i = 0; i < n; i++)
        {
            cin >> a[i];
        }
        sort(a, a + n);
        int ans = 0;
        // w1 < w2 且 w3 < w2
        for (int i = 1; i < n; i++)
        {
            ans = max(a[i] - a[0] + a[i] - a[i - 1], ans);
        }
        // w1 > w2 且 w3 > w2
        for (int i = 0; i < n - 2; i++)
        {
            ans = max(ans, a[n - 1] - a[i] + a[i + 1] - a[i]);
        }
        cout << ans << endl;
    }
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值