思路
这是一道贪心题。我们先考虑更赛牛。
- 首先,一个草如果要供最多牛食用,它就要尽可能远离最远的牛,这样才能保证另一端更多的牛能吃到。这样一格草就能最多满足 只同一种牛的食用需求。
- 但是,如果第 只牛已经靠近另一端,
已经超出了草地
的距离,我们就将最后一格草放在草地的最末尾。这样就能放置最少的草地就能满足所有的更赛牛。
- 荷斯坦牛的方法显然也类似,要尽可能满足最多的牛,它要尽量放置在 的位置,这保证和之前不会重复。因为
位置的牛是唯一的,所以
位置肯定没有被占用。
- 我们同时也要考虑荷斯坦牛最后一格草超出边境的问题。因为边界已经被更赛牛占用,我们就从 到
依次遍历找到空的格子放上就行了。一定要遍历到
或者
,如果遍历到
过不了样例的最后一小点(
)。
- 最后记得统计喂饱所有奶牛所需的最小草地数量,循环一遍即可。
代码
#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<queue>
#include<map>
#include<algorithm>
using namespace std;
// 快读
inline int read()
{
int x = 0,f = 1;char ch = getchar();
while (ch < '0' or ch > '9'){if (ch == '-') f = -1;ch = getchar();}
while (ch >= '0' and ch<='9'){x = x * 10 + ch - 48;ch = getchar();}
return x * f;
}
int main() {
int t = read();
while(t--) {
//定义变量及输入
int a = read(),k = read(),ans = 0;
char c[100005],d[100005];
for(int i = 1;i <= a;i++) cin>>c[i],d[i] = '.';
//更赛牛
for(int i = 1;i <= a;i++) {
if(c[i] == 'G') {
//未超出边界时
if(i + k <= a) {
d[i + k] = 'G';
}
//超出边界时
else {
d[a] = 'G';
}
//满足了牛的需求后记得加跳过已经满足的部分。
i += 2 * k;
}
}
//荷斯坦牛
for(int i = 1;i <= a;i++) {
if(c[i] == 'H') {
未超出边界时
if(i + k < a) {
d[i + k] = 'H';
}
//超出边界时
else {
for(int j = a;j >= 1;j--) {
if(d[j] == '.'){
d[j] = 'H';
break;
}
}
}
i += 2 * k;
}
}
//统计ans和输出
for(int i = 1;i <= a;i++) if(d[i] != '.') ans++;
printf("%d\n",ans);
for(int i = 1;i <= a;i++) cout<<d[i];
printf("\n");
}
return 0;
}