这道题意思是:
给你一个长度为9的字符串,且只有3个a、3个g、3个o
问,你可以选择删除一段连续的串或者单个的字符也可以不删,最多会出现几个三子相连的子串
比如:agoagoago只有将两种删除完,才能得到三子相连,所以是1
aaoogggoa,首先里面有一个三子相连(ggg),然后我们删除ggg这三个连续的字符,之后会出现ooo,删除ooo,之后会出现aaa,所以答案是3
我们可以分析到:
先检测原串中有几个三子相连,且只会得到0个,1个或者3个,不会有2个
如果原串有一个三子相连,那么最后答案就是2,因为剩下的没有现成三子相连的6个字符删除某些字符只能剩下一个三子相连,且最后一定会剩下一个
如果原串有0个三子相连,那么删除任意个字符后一定会剩下至少一个三子相连,下文续:
想法一:如果里面有一个二子相连(假设为a类字符),并且和另外一个字符中间需要删除的部分中只由一种字符(假设为b类字符)构成,那么我们删除中间的b类字符让二子相连变成三子相连,剩下的另外一种字符一定会通过删完a类字符和b类字符,最后剩下来,又得到一个三子相连
想法二:但是我们不去记录素有二子相连中间与第三子中间的字符种类数,我们选择去枚举每一种字符,分别将它们移除现场,然后检查是否有三子相连,如果有,说明想法一成立,如果分别删除每一种字符都不能形成三子相连,那么说明要达到三子相连必须要删除中间的两种字符,一旦删除两种字符,就不可能有更多的三子相连
#include <iostream> #include <cstdio> #include <string> #include <algorithm> using namespace std; string str, str2; char ch[3] = { 'a','g','o' }; const char* _3[3] = { "aaa","ggg","ooo" }; int main() { int t; scanf("%d", &t); while (t--) { int result3 = 0; cin >> str; auto fun = [&](string& str) { int re = 3; do { size_t it = 0; for (int i = 0; i < 3; ++i) if ((it = str.find(_3[i])) != string::npos)result3++, str.erase(str.begin() + it, str.begin() + it + 3); } while (re-- && result3 != 3); }; fun(str); if (result3 == 3) puts("3"); else if (result3 == 1) puts("2"); else { size_t index; for (int i = 0; i <= 2; ++i) { string str2 = str; while ((index = str2.find(ch[i])) != string::npos) str2.erase(str2.begin() + index); fun(str2); if (result3)break; } if (result3)puts("2"); else puts("1"); } } }
感谢阅读,生活愉快~