题解 | #集合操作#

集合操作

https://ac.nowcoder.com/acm/contest/11173/C

集合操作

参考了大佬的代码:boringhaker 提交的代码

先將序列a排序。

如果 a[pos] 后边的数减去 k * p的平均值大于等于 a[pos - 1],就不需要管pos前边的数。
用后缀和找到 pos 的位置。

pos后边的数减去 (a[i] - key)/p*p
如果 k 依旧不为0,继续从大到小减去p。

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6+10;
int a[N];

signed main(){
    std::ios_base::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    int n, k, p;
    cin>>n>>k>>p;
    for(int i = 1; i <= n; i++){
        cin>>a[i];
    }
    sort(a+1, a+1+n);

    // 特判 
    if(p == 0){
        for(int i = 1; i <= n; i++){
            cout<<a[i]<<" ";
        }
        return 0;
    }

    int pos, key, sum = 0;
    a[0] = -LLONG_MAX;

    // 找到pos的位置 
    for(int i = n; i >= 1; i--){
        sum += a[i];
        if((sum - k*p)/(n-i+1) >= a[i-1]){
            pos = i;
            key = (sum - k*p)/(n-i+1);
            break;
        }
    }

    for(int i = n; i >= pos; i--){
        k -= (a[i] - key)/p;
        a[i] -= (a[i] - key)/p*p;
    }
    sort(a+1, a+1+n);

    for(int i = n; i >= pos; i--){
        if(k > 0){
            a[i] -= p;
            k--;
        }
        else{
            break;
        }
    }
    sort(a+1, a+1+n);

    for(int i = 1; i <= n; i++){
        cout<<a[i]<<" ";
    }

    return 0;
}
全部评论
输入 5 30 3 10 68 68 56 89 输出 10 47 47 47 50 这组数据好像不对。
点赞 回复 分享
发布于 2021-05-24 21:46

相关推荐

牛客618272644号:佬携程工作怎么样,强度大吗
点赞 评论 收藏
分享
10-11 17:45
门头沟学院 Java
走吗:别怕 我以前也是这么认为 虽然一面就挂 但是颇有收获!
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务