Educational Codeforces Round 86 (Rated for Div. 2) D. Multiple Testcases

https://codeforces.com/contest/1342/problem/D

 

简单的叙述一下题意:有n个不大于k的数记录在m数组中,现在呢,需要我们将这n个数分组,对每个组的限制是,对于任何1~k的数字X,每组中不小于X的数字的个数不能大于C【X】,C数组输入时给定。现在需要我们计算出最小的分组数

看个热闹的题解:在输入的数组M的时候呢,将每个数出现的次数记录在num数组中,这是为了下面计算比X大的数有多少个做一下铺垫,然后呢,计算一下M数组中大于任意X的数有多少,计算的时候是逆向的,因为逆向的话可以得出大于X的数字有多少个,计算分组的时候呢考虑需要分多少组,这里分组需要上取整(num[i]+c[i]-1)/c[i] 或者 ceil(1.0*num[i]/c[i]),因为下取整的话会有某组不满足C【x】,然后呢,就需要把M数组的各个数填到分的cnt个组中,那么问题来了,如何知道那么数应该填到哪里呢,那我们就想啊,如果排序完了,以cnt为循环节来依次将n个数放入到对应的组中,这个问题是不是就解决了呢?(o゜▽゜)o☆[BINGO!],是的,我们是这样处理的。

 

ok,上代码

 

#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <list>
#include <deque>
#include <queue>
#include <stack>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <iomanip>
#define ull unsigned long long
#define ll long long
#define pb push_back
#define mem(sum,x) memset(sum,x,sizeof(sum))
#define rep(i,start,end) for(int i=start;i<=end;i++)
#define per(i,end,start) for(int i=end;i>=start;i--)
#define tle ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
using namespace std;
const int mod = 1e9+7 ;
const int mxn = 1e6+7 ;
int _,n,k,t,u,v,w,ans,cnt,ok;
int m[mxn] , num[mxn] , c[mxn] , last[mxn] ;
vector<int>vc[mxn];
int main()
{
    tle;
    cin>>n>>k;
    rep(i,1,n) cin>>m[i] , num[ m[i] ]++;
    sort(m+1,m+1+n);
    rep(i,1,k) cin>>c[i] ;
    ok = -1 ;
    per(i,k,1)
    {
        num[i]+=num[i+1] ;
        ok = max(ok, (num[i]+c[i]-1)/c[i] );
    }
    cout<<ok<<endl;
    rep(i,1,n) vc[i%ok].pb(m[i]);
    rep(i,0,ok-1)
    {
        cout<<vc[i].size();
        for(auto j:vc[i])
            cout<<" "<<j;
        cout<<endl;
    }
}

 

posted @ 2020-04-27 18:36  __MEET  阅读(213)  评论(0编辑  收藏  举报