题目链接:https://codeforces.com/problemset/problem/1102/B
题目要求重点为必须k种颜色每种都得用至少一次(这需要优先考虑),然后每种颜色所上的元素必须不同(也就是相同元素不能涂一样的颜色,这就需要标记元素出现的最大次数了,如果最大次数大于k,则一定不符合题意。其他照常模拟。(这里一开始没想到二维标记,下次记住了)。
#include<bits/stdc++.h>
using namespace std;
bool vis1[5050][5050]; //二维数组标记该元素(一维)是否使用过该种颜色(二维)
bool vis2[5050]; //标记该颜色是否被使用过
int cnt[5050]; //计算相同元素出现的个数
int main()
{
int n,k;
while(cin>>n>>k)
{
memset(vis1,0,sizeof(vis1));
memset(vis2,0,sizeof(vis2));
memset(cnt,0,sizeof(cnt));
int a[5050],ans[5050]; //a为输入元素,ans为输出颜色(这里的两个数组后面都为其赋值了,所以不用初始化)
int flag=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
cnt[a[i]]++;
if(cnt[a[i]]>k) //如果相同元素的个数超过所给颜色种类数,必定NO(题目要求)
flag=1;
}
if(flag)
{
cout<<"NO"<<endl;
continue;
}
int use=0; //标记使用过的颜色数,这里要首先把k种元素都用过来一遍,再看其他的。
//(敬请参考,可能还有其他做法)
for(int i=1;i<=n;i++)
{
for(int j=1;j<=k;j++)
{
if(!vis1[a[i]][j]&&!vis2[j]&&use<k) //这是首先将k种元素都先用过1次,(一开始我就是不知道怎么实现这个操作)
{
vis1[a[i]][j]=1;
vis2[j]=1;
ans[i]=j;
use++;
break;
}
if(use==k&&!vis1[a[i]][j])
{
vis1[a[i]][j]=1;
ans[i]=j;
break;
}
}
}
cout<<"YES"<<endl;
for(int i=1;i<=n;i++)
{
if(i==n)
cout<<ans[i]<<endl;
else
cout<<ans[i]<<" ";
}
}
return 0;
}