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;
}
posted @ 2022-04-30 21:17  la-la-wanf  阅读(81)  评论(0编辑  收藏  举报