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; } }