zoukankan      html  css  js  c++  java
  • Codeforces 999D Equalize the Remainders (set使用)

    题目连接:Equalize the Remainders

    题意:n个数字,对m取余有m种情况,使得每种情况的个数都为n/m个(保证n%m=0),最少需要操作多少次? 每次操作可以把某个数字+1。输出最少操作次数,和操作后的序列(可以输出任意一种)。

    题解:用一个set来维护所有余数x(当前余数为x的数个数没凑够n/m个),对于每个数假设这个数的余数为t,当余数为t的数个数没凑够n/m时那这个数就不需要改变,如果已经凑够了,那就在set中找到第一个大于等于t的数(注意这里t可能比set中最大数的还要大,遇到这种情况就要将t变成set中最小数,举个例子m=5,余数为4和为0的数字凑够了,此时又来一个余数为4的数,该数应该变为余数为1)维护答案和序列,ans += (x-t+m)%m,out[i] += (x-t+m)%m。

    
    
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef pair<int,int> P;
     4 typedef long long LL;
     5 const int MAX_N =2e5+9;
     6 int N,M,T,S;
     7 LL vec[MAX_N];
     8 LL res[MAX_N]; // 当前模的个数
     9 set<int> s;
    10 LL out[MAX_N];
    11 int main()
    12 {
    13     while(cin>>N>>M){
    14         memset(res,0,sizeof(res));
    15         memset(out,0,sizeof(out));
    16         s.clear();
    17         for(int i=0;i<M;i++){
    18             s.insert(i);
    19         }
    20         for(int i=0;i<N;i++){
    21             scanf("%lld",&vec[i]);
    22         }
    23         LL ans =0 ;
    24         for(int i=0;i<N;i++){
    25             LL t = vec[i]%M;
    26             LL x ;
    27             if(t > *s.rbegin()) x = *s.begin();
    28             else x = *s.lower_bound(t);
    29             res[x] ++;
    30             if(res[x] == N/M) s.erase(x);
    31             ans += (x - t + M)%M;
    32             out[i] = (x - t + M)%M;
    33         }
    34         cout<<ans<<endl;
    35         for(int i=0;i<N;i++){
    36             printf("%lld ",vec[i] + out[i]);
    37         }
    38         cout<<endl;
    39     }
    40     return 0;
    41 }
  • 相关阅读:
    班课6
    lesson one
    班课5
    ES6之Proxy及Proxy内置方法
    ES6模板字符串
    ES6之Symbol
    ES6对象及ES6对象简单拓展
    ES6函数的拓展
    ES6数组及数组方法
    ES6字符串方法
  • 原文地址:https://www.cnblogs.com/doggod/p/9524922.html
Copyright © 2011-2022 走看看