P8898 [USACO22DEC] Feeding the Cows B

题目传送门

分析

开始想dp但是感觉又不太像,有点像贪心,开始想的是可以简化题目变成牛可以放到哪些地方吃草,牛可以吃草的区域为 $ S[$ i $] \pm K $,那我们把第一头牛直接放在 $ i + K \(的位置,发现\) i + K $的位置的牛同样可吃草,那我们只需在拿牛的时候放到最大可吃的右位置即为草 (在这范围内的牛就不管,反正在此区间的牛也可以吃到)

但我们发现是不是牛也可以在左边吃草呢,所以也记录一下上一块草的位置,看看当前的牛是不是可以吃到,可以我们就不拿牛

最后特判一下,如果我们现在拿着牛,到最后了我们就放下来,拿了不同的两种牛的话,就前面种棵草

AC code

#include<bits/stdc++.h>
using namespace std;

int main(){
	int t,n,k;
	string s;
	char a[100005];
	cin >> t;
	while(t--){
		cin >> n >> k >> s;
		int g=-1,h=-1,c=0,pg=-100005,ph=-100005;
		//g拿G牛的位置(-1表示没有在拿牛) c记录草的数量 pg记录G草的位置 
		for(int i=0;i<n;i++){
			//拿 
			if(g==-1&&s[i]=='G'&&i-pg>k){
				g = i;
			}
			else if(h==-1&&s[i]=='H'&&i-ph>k){
				h = i;
			}
			//放 
			if(i==n-1){
				if(g!=-1&&h!=-1){
					a[i] = 'G';
					a[i-1] = 'H';
				}
				else if(g!=-1) a[i] = 'G';
				else if(h!=-1) a[i] = 'H';
				else a[i] = '.';
			}
			else if(g!=-1&&i-g==k){
				a[i] = 'G';
				g = -1;
				pg = i;
			}
			else if(h!=-1&&i-h==k){
				a[i] = 'H';
				h = -1;
				ph = i;
			}
			else a[i] = '.';
		}
		for(int i=0;i<n;i++){
			if(a[i]!='.') c++;
		} 
		cout << c << endl;
		for(int i=0;i<n;i++){
			cout << a[i];
		}
		cout << endl;
	}
	return 0;	
}
posted @ 2023-12-13 20:58  Nijika  阅读(52)  评论(0)    收藏  举报