题意:
给你一个长度为n的序列和m种颜色,序列的每个元素可以被m种颜色涂上(也可以不涂),但是每种颜色涂的序列的个数都必须相同,而且同种颜色不能出现值相等的元素,让你输出涂的序列最长的情况。
思路:
因为每个颜色不能涂重复的元素,那么首先可以计算一下每种元素出现的次数,如果超过了m就可以直接丢弃。然后剩下的元素就都是可以涂的元素,但是每种颜色涂的数量要相同,那么time/m*m就是我要涂的总共的元素。
然后是要尽可能的多涂,那么重复多的元素应该先涂,让每种颜色都能涂上(涂不全就用剩下的最多的元素涂)然后每次涂完一个就换一个颜色涂,直接遍历涂完就可以了
代码:
#include<cstdio>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <math.h>
#include<vector>
#include<queue>
#include<map>
#define sc_int(x) scanf("%d", &x)
#define sc_ll(x) scanf("%lld", &x)
#define pr_ll(x) printf("%lld", x)
#define pr_ll_n(x) printf("%lld\n", x)
#define pr_int_n(x) printf("%d\n", x)
#define ll long long
using namespace std;
map<int,int>q;
const int N=1000000+100;
int n ,m,h;
struct lk{
int i;
int x;
}s[N];
int b[N],a[N];
bool cmp(lk x,lk y ){
if(q[x.x]!=q[y.x])
return q[x.x]>q[y.x];
return x.x<y.x;
}
void solve()
{
cin>>n>>m;
q.clear();
int time=0;
for(int i =1; i<=n;i++)
{
cin>>a[i];
if(q[a[i]]+1<=m){
s[++time]={i,a[i]};
q[a[i]]++;
}
}
sort(s+1,s+1+time,cmp);
int j=1;
time=(time/m)*m;
for(int i =1;i<=time;i++)
{
b[s[i].i]=j%m;
if(j%m==0)b[s[i].i]=m;
j=(j+1)%m;
}
for(int i =1;i<=n;i++){
cout<<b[i]<<" ";
b[i]=0;
}
cout<<endl;
return ;
}
int main()
{
int t;
sc_int(t);
while(t--)solve();
return 0;
}
/*
1 3 5 6
1 3 5 8
2 4 5 9
*/