贡献法:USACO 2021 December Contest Bronze:孤独的照片

Farmer John 最近购入了 N 头新的奶牛,每头奶牛的品种是更赛牛(Guernsey)或荷斯坦牛(Holstein)之一。

奶牛目前排成一排,Farmer John 想要为每个连续不少于三头奶牛的序列拍摄一张照片。

然而,他不想拍摄这样的照片,其中只有一头牛的品种是更赛牛,或者只有一头牛的品种是荷斯坦牛——他认为这头奇特的牛会感到孤立和不自然。

在为每个连续不少于三头奶牛的序列拍摄了一张照片后,他把所有「孤独的」照片,即其中只有一头更赛牛或荷斯坦奶牛的照片,都扔掉了。

给定奶牛的排列方式,请帮助 Farmer John 求出他会扔掉多少张孤独的照片。

如果两张照片以不同位置的奶牛开始或结束,则认为它们是不同的。

输入格式

输入的第一行包含 N。

输入的第二行包含一个长为 N 的字符串。如果队伍中的第 i 头奶牛是更赛牛,则字符串的第 i 个字符为 G。否则,第 i 头奶牛是荷斯坦牛,该字符为 H

输出格式

输出 Farmer John 会扔掉的孤独的照片数量。

数据范围

3≤N≤5×105

输入样例:
5
GHGHG
输出样例:
3
样例解释

这个例子中的每一个长为 3 的子串均恰好包含一头更赛牛或荷斯坦牛——所以这些子串表示孤独的照片,并会被 Farmer John 扔掉。

所有更长的子串(GHGHHGHG 和 GHGHG)都可以被接受。

可以通过 l 和 r 数组记录 每头牛左右两边有多少连续的不同种类的牛数量

然后孤独照片数量就是通过 l[i] 和 r[i] 分三类相加得出

找出当前这个牛的左边相邻的连续不同的牛 *  右边的相邻连续不同的牛 + 左边的不同牛的长度 - 1 + 右边不同的牛的长度 - 1

为什么左右两边的长度要减1,因为照片长度至少3,假如是 GHHHH,右边不同长度的牛为4,可方案为,GHH,GHHH,GHHHH,为3,需要减一。

AC code:

#include<bits/stdc++.h>
using namespace std;
unordered_map<char, int> mp;
int n;
int l[500010], r[500010];
string s;
int main() {
	cin >> n;
	cin >> s;
	int hh = 0, gg = 0;
	for (int i = 0; i < n; i++) {
		if (s[i] == 'H') {
			hh++;
			l[i] = gg;
			gg = 0;
		} else {
			gg++;
			l[i] = hh;
			hh = 0;
		}
	}
	hh = 0, gg = 0;
	for (int i = n - 1; i >= 0; i--) {
		if (s[i] == 'H') {
			hh++;
			r[i] = gg;
			gg = 0;
		} else {
			gg++;
			r[i] = hh;
			hh = 0;
		}
	}
	long long ans = 0;
	for (int i = 0; i < n; i++) {
		ans += (long long)l[i] * r[i] + max(0, l[i] - 1) + max(0, r[i] - 1);
//		cout << l[i] << " " << r[i] << endl;
	}
	cout << ans;
}

### USACO 2016 Copper Problems and Information USACO(United States of America Computing Olympiad)是一个面向全球编程爱好者的竞赛平台,尤其受到高中生欢迎。对于2016年的铜级别比赛,以下是几个具有代表性的题目及其描述: #### Promotion Counting 【USACO 2016 January Contest, Bronze】 在这个问题中,给定一组奶牛的位置以及它们晋升的情况,需要统计特定条件下能够被提升的奶牛数量[^1]。 ```cpp // 这里提供的是一个简化版的例子用于说明逻辑结构而非具体实现细节 #include <iostream> using namespace std; int main(){ int n; cin >> n; // 处理输入并计算结果... } ``` #### Cities and States 【USACO 2016 December Contest, Silver but mentioned in bronze context】 此题涉及城市名称和州名之间的匹配关系。给出多个城市的名称与其所在的州缩写,要求找出满足一定条件的城市对的数量[^2]。 ```cpp // 同样仅展示框架性代码片段 string city_names[], state_codes[]; for (each pair){ check_condition_and_count(); } cout << count_result; ``` #### Angry Cows 【USACO 2016 January Contest, Bronze】 这是一个关于覆盖区间的问题。假设有一系列位于直线上的目标点(草堆),通过调整发射物(奶牛)的影响范围来尽可能高效地摧毁所有目标。任务是要找到最小的有效影响半径使得全部目标都能受到影响[^3]。 ```cpp vector<int> positions; // 存储各个草堆的位置 double findMinRadius(int k){ /* ... */ } ``` #### Circular Barn 【USACO 2016 February Contest, Bronze】 该问题是围绕着优化路径展开的。在一个环形布局下安排访问顺序,目的是使总的行走距离最短。解决方案涉及到遍历不同的起始位置,并评估由此产生的总成本,最终选取最优解[^4]。 ```cpp LL solveOptimalPath(vector<int>& distances){ LL bestCost = numeric_limits<LL>::max(); for(size_t start=0 ;start<distances.size();++start){ calculate_cost_from_start(start); update_best_if_better(bestCost,currentCost); } return bestCost; } ``` 这些例子展示了不同类型的算法挑战,从简单的计数到更复杂的贪心策略或是动态规划方的应用。每个问题都旨在测试参赛者的基础编程技能以及解决问题的能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值