Farmer John has recently acquired NN new cows (3≤N≤5×105)(3≤N≤5×105), each of whose breed is either Guernsey or Holstein.
The cows are currently standing in a line, and Farmer John wants take a photo of every sequence of three or more consecutive cows. However, he doesn't want to take a photo in which there is exactly one cow whose breed is Guernsey or exactly one cow whose breed is Holstein --- he reckons this singular cow would feel isolated and self-conscious. After taking a photo of every sequence of three or more cows, he throws out all of these so-called "lonely" photos, in which there is exactly one Guernsey or exactly one Holstein.
Given the lineup of cows, please help Farmer John determine how many lonely photos he will throw out. Two photos are different if they start or end at different cows in the lineup.
The first line of input contains NN.
The second line contains a string of NN characters. The iith character is G if the iith cow in the line is a Guernsey. Otherwise, it will be an H and the iith cow is a Holstein.
Please print the number of photos Farmer John will throw out because they are lonely.
5 GHGHG
3
Every substring of length 3 in this example contains exactly one cow whose breed is Guernsey or exactly one cow whose breed is Holstein --- so these substrings represent lonely photos and would be thrown out by Farmer John. All longer substrings (GHGH, HGHG, and GHGHG) are acceptable to him.
Problem credits: Nick Wu
[/hide]
(Analysis by Nick Wu)
We need to count the number of substrings of length 3 that contain exactly one G or one H.
The most direct solution involves checking every substring of length at least 3. There are O(N2)O(N2) such substrings to check, and each one takes O(N)O(N) time to validate, for a total runtime of O(N3)O(N3).
To improve the performance of this solution, we can choose to check substrings in a specific order. In particular, fix the leftmost character in the substring and then start scanning to the right. If we have seen at least three characters and exactly one of them is G or one of them is H, increment a counter. Loop over all leftmost characters and then print the counter at the end. The approach of this solution is O(N2)O(N2).
#include <iostream> #include <string> int main() { int n; std::string s; std::cin >> n >> s; int ans = 0; for(int i = 0; i < (int)s.size(); i++) { int g = 0; int h = 0; for(int j = i; j < (int)s.size(); j++) { if(s[j] == 'G') g++; else h++; if(g+h >= 3 && (g==1 || h==1)) ans++; } } std::cout << ans << "\n"; }
It is possible to solve this problem in O(N)O(N). For each character, let's count the number of photos in which that character is the odd one out. In the case where that character is G, the substring must either have at least two H's on one side of it or at least one H on both sides of it and no other occurrences of G. We can count the number of mismatching characters directly to the left and to the right and account for both cases.
#include <iostream> #include <string> using namespace std; int main() { int n; string s; cin >> n >> s; int64_t ans = 0; for(int i = 0; i < n; i++) { int64_t lhs = 0; if(i > 0 && s[i-1] != s[i]) { lhs++; for(int k = i-2; k >= 0 && s[k] == s[i-1]; k--) lhs++; } int64_t rhs = 0; if(i+1 < n && s[i+1] != s[i]) { rhs++; for(int k = i+2; k < n && s[k] == s[i+1]; k++) rhs++; } ans += lhs * rhs + max(lhs-1, (int64_t)0) + max(rhs-1, (int64_t)0); } cout << ans << "\n"; }
[/hide]
翰林课程体验,退费流程快速投诉邮箱: yuxi@linstitute.net 沪ICP备2023009024号-1