zoukankan      html  css  js  c++  java
  • [CF1328F] Make k Equal

    Solution

    枚举选择一个中间点,计算把边上压到中间这条线上的答案

    压的时候要考虑两边压和单边压的情况

    (以下代码中的二分显得很累赘,纯粹为了偷懒而出现)

    using namespace std;
    
    #define int long long
    const int N = 200005;
    
    int n,k,a[N],pre[N],suf[N],ans=1e18;
    map<int,int> mp;
    
    signed main() {
        ios::sync_with_stdio(false);
        cin>>n>>k;
        for(int i=1;i<=n;i++) cin>>a[i];
        sort(a+1,a+n+1);
        for(int i=1;i<=n;i++) {
            pre[i]=pre[i-1]+a[i];
        }
        for(int i=n;i>=1;--i) {
            suf[i]=suf[i+1]+a[i];
        }
        for(int i=1;i<=n;i++) mp[a[i]]++;
        for(auto i:mp) if(i.second>=k) {
            cout<<0<<endl;
            return 0;
        }
        for(int i=1;i<=n;i++) {
            int x=a[i];
            int e=upper_bound(a+1,a+n+1,x)-lower_bound(a+1,a+n+1,x);
            int g=n-(upper_bound(a+1,a+n+1,x)-a)+1;
            int l=lower_bound(a+1,a+n+1,x)-a-1;
            int sg=suf[n-g+1];
            int sl=pre[l];
            int tmp=sg-g*x+l*x-sl-(n-k);
            ans=min(ans,tmp);
            if(n-l>=k) {
                int tx=sg-g*x-(n-l-k);
                ans=min(ans,tx);
            }
            if(n-g>=k) {
                int tx=l*x-sl-(n-g-k);
                ans=min(ans,tx);
            }
            //cout<<l<<" "<<e<<" "<<g<<endl;
        }
        cout<<max(0ll,ans);
    }
    
    
  • 相关阅读:
    双指针
    二维数组 查找常用字符
    将数组分为相等的三部分
    交换 排序
    买股票
    双指针 回文数
    双指针
    测试SM图床
    cnpm,vue等命令不识别的问题废人解决方案
    typeof面试题解答
  • 原文地址:https://www.cnblogs.com/mollnn/p/12579514.html
Copyright © 2011-2022 走看看