这道题意思是:
给你一个长度为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");
}
}
}
感谢阅读,生活愉快~