• codeforces-1328F-Make k Equal


    codeforces-1328F-Make k Equal

    传送门:https://codeforces.com/contest/1328/problem/F

    题意:把n个数变成k个相同的数 每次可以把n个数里最大的-1或最小的+1,问最小改变次数

    我们可以枚举,把n个数变成k个a[i](这个相同的数一定是数组里的数,因为如果不是,那么改变次数一定会比正常多)

    如果相同的数大于k个,那么改变次数为0,特判掉

    有三种情况,一种是只动前面,一种只动后面,还有就是前后都动

    因为是改变最大或最小的数,所以我们只有把所有小于a[i]的数变成a[i]-1(或者大于a[i]的数变成a[i]+1)才能进行下一次的改变

    然后接着考虑,在什么情况下可以动前面呢,当然是他前面的数大于(k-1)个,同理,在他后面的数大于(k-1)个时才可以动后面,然后在任何情况下都可以前后都动((在i==1)时就相当于是动后面结果不冲突)

    以只动前面为例

     化简一下发现

    就是i*(a[i]-1)-a[i]的前缀和+k,提前搞一个前缀和可以降低时间复杂度

    只动后面同理

    动两边,这时相等的数的个数恰好为n,把他们都搞成a[i]然后再减掉多余的

    记录好前缀和 和(后缀和?)就可以用o(n)的复杂度解决掉这个问题了

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define ll long long
     4 const ll inf=1e17;
     5 ll a[200009];
     6 ll cnt[200009];
     7 ll sumq[200009],sumh[200009];
     8 int main()
     9 {
    10     int n,k;
    11     ll ans=inf;
    12     scanf("%d%d",&n,&k);
    13     for(int i=1; i<=n; i++)
    14     {
    15         scanf("%lld",&a[i]);
    16     }
    17     sort(a+1,a+1+n);
    18     for(int i=1; i<=n; i++) sumq[i]=sumq[i-1]+a[i];
    19     for(int i=n; i>=1; i--) sumh[i]=sumh[i+1]+a[i];
    20     for(int i=1; i<=n; i++)
    21     {
    22         if(a[i]==a[i-1])cnt[i]=cnt[i-1]+1;
    23         else cnt[i]=1;
    24         if(cnt[i]>=k)
    25         {
    26             puts("0");
    27             return 0;
    28         }
    29     }
    30     for(int i=1; i<=n; i++)
    31     {
    32         if(i>=k)
    33         {
    34             ll tem1=i*(a[i]-1)-sumq[i]+k;
    35             ans=min(tem1,ans);
    36         }
    37         if(n-i+1>=k)
    38         {
    39             ll tem2=n-i+1;
    40             tem2=sumh[i]-tem2*(a[i]+1)+k;
    41             ans=min(tem2,ans);
    42         }
    43         if(i<k&&(n-i+1)<k)
    44         {
    45             ll tem3=i*a[i]-sumq[i]+sumh[i]-(n-i+1)*a[i]-(n-k);
    46             ans=min(tem3,ans);
    47         }
    48     }
    49     printf("%lld
    ",ans);
    50     return 0;
    51 }

     

  • 相关阅读:
    isequal 和startswith 使用
    UVa10340
    UVa1368
    UVa455
    UVa1225
    UVa1586
    UVa 1585
    UVa10082
    UVa272
    NYOJ1
  • 原文地址:https://www.cnblogs.com/YangKun-/p/12618922.html
Copyright © 2020-2023  润新知