B2. Wonderful Coloring - 2
题目的基本意思:
1:每个元素要么不涂,要么只能涂一种颜色;
2:每一种颜色涂的元素两两都是不相同的;
3:每一种颜色涂的元素的个数时相同的;
4:最后序列中涂的元素的个数要最大;
解题的思路:
1:去掉没必要涂的元素
(1)该元素在序列中的个数要大于k(k表示颜色的总数),将超过k的那部分直接用0表示即可,不用涂;可以考虑先把每个元素出现前k次的保存在vector数组q中。
2:为了保证每一种颜色涂的元素的个数时相同的,所以最后涂的元素的总个数一定是k的整数倍,所以存在q中的元素的总数不能整除k时,考虑删除多余的元素知道可以整除k为止,这样也可以保证最后序列中涂的元素的个数要最大。
3:每一种颜色涂的元素两两都是不相同的,考虑将元素的大小进行排序,为了保证输出的时候还是原来的顺序,我们不改变元素本身的顺序,而是将他们的下标改变顺序,就是元素本身大的他的下标就在前面。最后ans数组就是用来保存答案,依次从q的前后用1 2 3……k 1 2……来涂色;
4:注意数组的初始化为0;
样例模拟
input(随便模拟一个)
11 3(11个元素,上3中颜色)
3 1 1 1 1 10 3 4 10 2 10
数组名称 | 里面的值(下标从0开始) |
---|---|
a[] | 3 1 1 1 1 10 3 4 10 2 10 |
q 里面的元素为a中所选元素的下标 | 0 1 2 3 |
q 里面的元素为a中所选元素的下标 | 0 1 2 3 5 6 7 8 9 |
q 里面的元素对应a[]中对应的值 | 3 1 1 1 10 3 4 10 2 //由于1的个数有4个,当我们只能保存3个 |
排序后的q | 1 2 3 9 0 6 7 5 8 //根据上一行排序而来 |
ans[] | ans[1]=1,ans[2]=2,ans[3]=3 |
ans[] | ans[1]=1,ans[2]=2,ans[3]=3,ans[9]=1,ans[0]=2,ans[6]=3 |
ans[] | ans[1]=1,ans[2]=2,ans[3]=3,ans[9]=1,ans[0]=2,ans[6]=3,ans[7]=1,ans[5]=2,ans[8]=3 |
AC代码
(由于数组的初始化,时间用了850ms)
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int N = 2e5 + 10;
int a[N], ha[N];
int ans[N];
bool cmp(int i, int j) {
return a[i]<a[j];
}
int main() {
int t;
cin >> t;
while (t--) {
int n, k;
cin >> n >> k;
vector<int> q;
memset(ha, 0, sizeof(ha));
memset(a, 0, sizeof(a));
memset(ans, 0, sizeof(ans));
for (int i = 0; i < n; i++) {
cin >> a[i];
ha[a[i]]++;
if (ha[a[i]] <= k)q.push_back(i);
}
while (q.size() % k != 0)q.pop_back();
sort(q.begin(), q.end(), cmp);
for (int i = 0; i < q.size(); i++) {
ans[q[i]] = i % k + 1;
}
for (int i = 0; i < n; i++)
cout << ans[i] << " ";
cout << endl;
}
return 0;
}
小优化(为了不每一次操作都要初始化,我可以全部弄成vector数组)
#include<iostream>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
//const int N = 2e5 + 10;
//int a[N], ha[N];
//
//int ans[N];
//bool cmp(int i, int j) {
// return a[i]<a[j];
//}
int main() {
int t;
cin >> t;
while (t--) {
int n, k;
cin >> n >> k;
**vector<int> q, a(n+10), ha(n + 10), ans(n+10);**
for (int i = 0; i < n; i++) {
cin >> a[i];
ha[a[i]]++;
if (ha[a[i]] <= k)q.push_back(i);
}
while (q.size() % k != 0)q.pop_back();
sort(q.begin(), q.end(), [&](int i, int j) {return a[i] < a[j]; });
for (int i = 0; i < q.size(); i++) {
ans[q[i]] = i % k + 1;
}
for (int i = 0; i < n; i++)
cout << ans[i] << " ";
cout << endl;
}
return 0;
}