B2. Wonderful Coloring - 2 【模拟+简洁优化】
链接
Problem - 1551B2 - Codeforces 难度:1400 类型:涂色模拟
题目
Example
input
6 10 3 3 1 1 1 1 10 3 10 10 2 4 4 1 1 1 1 1 1 1 13 1 3 1 4 1 5 9 2 6 5 3 5 8 9 13 2 3 1 4 1 5 9 2 6 5 3 5 8 9 13 3 3 1 4 1 5 9 2 6 5 3 5 8 9
output
1 1 0 2 3 2 2 1 3 3 4 2 1 3 1 0 0 1 1 0 1 1 1 0 1 1 1 0 2 1 2 2 1 1 1 1 2 1 0 2 2 1 1 3 2 1 3 3 1 2 2 3 2 0
题意
n个数字,k种颜色,要给这些数字涂色使得涂色数目最多,且相同数字不能涂一样的颜色,每个颜色涂的数目相等(颜色用1~k表示)
题解
多于k的数字不用再入队涂色了,假设有m个数字入队,这部分可以进行涂色,但是要保证每个颜色数目相等且相同数字涂色不同。
这m个数字只有k的倍数可以涂色,而涂色方式不能每个1开始涂,应该1~k涂一轮再开始下一轮,以此反复
AC代码
#include<bits/stdc++.h> using namespace std; typedef pair<int,int> PII; const int N = 2e5 + 10; queue<int> v[N]; int res[N]; int main() { int t; cin>>t; while(t--) { int n, k, x; scanf("%d%d", &n, &k); for(int i = 1; i <=n; i ++) res[i] = 0; for(int i = 1; i <=n; i ++) while(v[i].size()) v[i].pop(); for(int i = 1; i <=n; i ++) { scanf("%d", &x); if(v[x].size()<= k) v[x].push(i); } int m = 0;//妙妙屋1--没有限制,只要是入队的都能直接轮流涂色v[x].size()<= k for(int i = 1; i <= n; i ++) m+=v[i].size(); m-=m%k; int l= 0;//妙妙屋2-- 1~k依次涂色 for(int i = n; i > 0 ; i --) { int xx = i; while(v[xx].size()) { res[v[xx].front()] = ++l; v[xx].pop(); l %= k; if(--m <=0)break; } if(m <=0)break; } for(int i = 1; i <= n; i ++)cout << res[i]<< ' '; cout << '\n'; } return 0; }