Codeforces Round #375 (Div. 2) C 模拟

题目传送门:http://codeforces.com/contest/723/problem/C


题意:给n首歌曲1,2...n然后a1,a2,...an表示1th歌曲由a1th乐队演唱,小明喜欢前m个乐队,小明可以随意改变歌曲的演唱者,问最少要操作多少次才能让小明喜欢的乐队中唱歌最少的乐队唱的歌尽量多,输出最少乐队唱的歌曲数,最少操作次数,操作后的演唱名单


思路:昨天比赛的时候没做出来,当时思路其实并不清楚就开始敲,结果越敲越糊涂,今天早上起来再看看,发现并不是难题,暴力就好了。关键是先找出最少乐队唱的歌曲数,最少操作次数。然后再做这题就简单好多了。昨天可能是stl题做多了,就各种stl瞎搞,也没搞出来。反正n,m都是2000,暴力就可以,而且暴力后发现时间用的也不是很多。


代码如下:

#include <iostream>
#include <algorithm>
#include <cstring>
#include <stdio.h>
#include <string>
#include <cmath>
#include <queue>
#include <set>
#include <map>

using namespace std;
#define   lson          l,m,rt<<1
#define   rson          m+1,r,rt<<1|1
#define   ll            long long
#define   ull           unsigned long long
#define   mem(n,v)      memset(n,v,sizeof(n))
#define   MAX           2005
#define   MAXN          2000005
#define   PI            3.1415926
#define   E             2.718281828459
#define   opnin         freopen("text.in.txt","r",stdin)
#define   opnout        freopen("text.out.txt","w",stdout)
#define   clsin         fclose(stdin)
#define   clsout        fclose(stdout)
#define   haha1          cout << "haha1"<< endl
#define   haha2          cout << "haha2"<< endl
#define   haha3          cout << "haha3"<< endl

const int    INF    =   0x3f3f3f3f;
const ll     INFF   =   0x3f3f3f3f3f3f3f3f;
const double pi     =   3.141592653589793;
const double inf    =   1e18;
const double eps    =   1e-8;
const ll     mod    =   1e9+7;
const ull    mx     =   133333331;

int a[MAX]; //key:song,value:band
int b[MAX]; //key:band,value:song_number
struct like
{
    int songnum;
    int band;
    friend bool operator < (like a,like b){
        return a.songnum < b.songnum;
    }
    like(int b = 0,int s = 0):songnum(s),band(b) {}
};
like lll[MAX];
int main()
{
    mem(b,0);
    int n,m;
    cin >> n >> m;
    int cnt  = 0;
    int g = 0;
    int ans = n / m;
    for(int i=1;i<=n;i++){
        scanf("%d",a+i);
        if(a[i] <= m)
            b[a[i]]++;
        else g++;
    }
    for(int i=1;i<=m;i++){
        if(b[i] < ans)
            cnt += (ans-b[i]);
    }
    int cnt1 = cnt;
   for(int i=1;i<=m;i++){
        lll[i].band = i;
        lll[i].songnum = b[i];
    }
    sort(lll+1,lll+m+1);
    while(cnt > 0){
        if(g >0){
            for(int i=1;i<=n;i++){
                if(a[i] > m){
                    lll[1].songnum++;
                    g--;
                    cnt--;
                    a[i] = lll[1].band;
                    break;
                }
            }
            sort(lll+1,lll+m+1);
        }
        else{
            for(int i=1;i<=n;i++){
                if(a[i] == lll[m].band){
                    lll[1].songnum++;
                    lll[m].songnum--;
                    cnt--;
                    a[i] = lll[1].band;
                    break;
                }
            }
            sort(lll+1,lll+m+1);
        }
    }
    cout << ans << ' ' << cnt1 <<endl;
    for(int i=1;i<=n;i++){
        printf("%d ",a[i]);
    }

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值