题目大意:涂色游戏,求最后涂色序列;
要求:1.每个元素,可涂,可不涂
2.同种颜色的颜色数相等
3.数值相等的元素不能涂同种颜色
解题思路:先排除确定不涂的元素,再直接对剩余元素直接涂色;
确定不涂的元素:数值相等的元素个数超出所给的颜色数了的多出的那些元素确定不涂。
最后 确定要涂的元素数%颜色数k == 0,若确定要涂的元素数%颜色数k != 0 ,则找余数个未确定是否涂色的元素,将它们变为确定不涂色的元素;
最最后,顺序涂色,按下标重新排序输出。
PS:大无语事件:我就不明白之前写的错在哪了,看了一堆题解,才写出现在这个。。。。。
WA1:
#include <iostream>
#include <cstring>
#include <bits/stdc++.h>
using namespace std;
const int N =2e5+10;
struct point{
int w, idx, color, cnt;
}a[N];
int c[N];
vector<int> st;
bool cmp(point a, point b)
{
if(a.cnt != b.cnt) return a.cnt > b.cnt;
if(a.w != b.w) return a.w<b.w;
return a.idx<b.idx;
}
bool cmp2(point a, point b)
{
return a.idx < b.idx;
}
int main()
{
int t;
cin>>t;
while(t --)
{
int n, k, pos = 0;
cin>>n>>k;
for(int i = 1; i<= n; i++)
{
cin>>a[i].w;
a[i].idx = i;
st.push_back(a[i].w);
}
for(int i = 1; i<=n; i++)
{
int num = count(st.begin(),st.end(),a[i].w);
a[i].cnt = num;
// cout<<a[i].cnt<<endl;
}
sort(a+1, a+n+1, cmp);
int color = 1;
for(int i = 1; i<= n; i++)
{
// cout<<"value : "<<a[i].w<<" color: ";
if(i > k)
{
if(a[i-k].color == color && a[i-k].w == a[i].w) a[i].color = 0;
else if(a[i-1].color == 0 && a[i-1].w == a[i].w) a[i].color = 0;
else a[i].color = color++;
}
else
{
a[i].color = color;
color++;
}
if(color == k+1) color = 1;
c[a[i].color]++;
if(c[a[i].color] > n/k && a[i].color != 0) a[i].color = 0;
// cout<<a[i].color<<" "<<endl;
}
//cout<<endl;
sort(a+1, a+n+1, cmp2);
for(int i = 1; i<=n; i++)
{
cout<<a[i].color<<' ';
}
cout<<endl;
memset(a, 0, sizeof(a));
memset(c, 0, sizeof(c));
st.clear();
}
return 0;
}
WA2:
#include <iostream>
#include <cstring>
#include <bits/stdc++.h>
using namespace std;
const int N =2e5+10;
struct point{
int w, idx, color, cnt;
}a[N];
int c[N];
bool cmp(point a, point b)
{
if(a.w!=b.w) return a.w<b.w;
return a.idx < b.idx;
}
bool cmp2(point a, point b)
{
return a.idx < b.idx;
}
int main()
{
int t;
cin>>t;
while(t --)
{
int n, k, pos = 0;
cin>>n>>k;
for(int i = 1; i<= n; i++)
{
cin>>a[i].w;
a[i].idx = i;
}
sort(a+1, a+n+1, cmp);
int color = 1;
int cnt = 1;
a[1].color = 1;
for(int i = 2; i<= n; i++)
{
if(a[i].w == a[i-1].w)
{
cnt++;
if(cnt>k)
{
a[i].color = 0;
continue;
}
}
else
{
cnt = 1;
}
color++;
if(color > k) color = 1;
a[i].color = color;
}
int i = n;
if(a[i].color != k)
{
a[i].color = 0;
i--;
}
sort(a+1, a+n+1, cmp2);
for(int i = 1; i<=n; i++)
{
cout<<a[i].color<<' ';
}
cout<<endl;
memset(a, 0, sizeof(a));
}
return 0;
}
AC:(这是看了别人的题解改的)
#include <iostream>
#include <cstring>
#include <bits/stdc++.h>
using namespace std;
const int N =2e5+10;
struct point{
int w, idx, color;
}a[N];
int c[N];
bool cmp(point a, point b)
{
return a.w<b.w;
}
bool cmp2(point a, point b)
{
return a.idx < b.idx;
}
int main()
{
int t;
cin>>t;
while(t --)
{
int n, k;
cin>>n>>k;
for(int i = 1; i<= n; i++)
{
cin>>a[i].w;
a[i].idx = i;
a[i].color = -1;
if(c[a[i].w] == k) a[i].color = 0;
else c[a[i].w]++;
//cout<<c[a[i].w]<<endl;
}
sort(a+1, a+n+1, cmp);
int cnt = 0;
for(int i = 1; i<= n; i++)
{
if(a[i].color == -1) cnt++;
}
//cout<<cnt<<endl;
int i = n;
while(cnt % k)
{
if(a[i].color == -1)
{
a[i].color = 0;
cnt--;
}
i--;
}
int color = 1;
for(int i = 1; i<= n; i++)
{
if(a[i].color == -1) a[i].color = color++;
if(color == k+1) color = 1;
}
sort(a+1, a+n+1, cmp2);
for(int i = 1; i<=n; i++)
{
cout<<a[i].color<<' ';
}
cout<<endl;
memset(a, 0, sizeof(a));
memset(c, 0, sizeof(c));
}
return 0;
}