题目描述
#1039 : 字符消除
时间限制:1000ms
单点时限:1000ms
内存限制:256MB
描述
小Hi最近在玩一个字符消除游戏。给定一个只包含大写字母"ABC"的字符串s,消除过程是如下进行的:
1)如果s包含长度超过1的由相同字母组成的子串,那么这些子串会被同时消除,余下的子串拼成新的字符串。例如"ABCCBCCCAA"中"CC","CCC"和"AA"会被同时消除,余下"AB"和"B"拼成新的字符串"ABB"。
2)上述消除会反复一轮一轮进行,直到新的字符串不包含相邻的相同字符为止。例如”ABCCBCCCAA”经过一轮消除得到"ABB",再经过一轮消除得到"A"
游戏中的每一关小Hi都会面对一个字符串s。在消除开始前小Hi有机会在s中任意位置(第一个字符之前、最后一个字符之后以及相邻两个字符之间)插入任意一个字符('A','B'或者'C'),得到字符串t。t经过一系列消除后,小Hi的得分是消除掉的字符的总数。
请帮助小Hi计算要如何插入字符,才能获得最高得分。
输入
输入第一行是一个整数T(1<=T<=100),代表测试数据的数量。
之后T行每行一个由'A''B''C'组成的字符串s,长度不超过100。
输出
对于每一行输入的字符串,输出小Hi最高能得到的分数。
提示
第一组数据:在"ABCBCCCAA"的第2个字符后插入'C'得到"ABCCBCCCAA",消除后得到"A",总共消除9个字符(包括插入的'C')。
第二组数据:"AAA"插入'A'得到"AAAA",消除后得到"",总共消除4个字符。
第三组数据:无论是插入字符后得到"AABC","ABBC"还是"ABCC"都最多消除2个字符。
样例输入
3
ABCBCCCAA
AAA
ABC
样例输出
9
4
2
题目分析
1 首先我们根据题目要求得到我们的操作要求
我们可以插入一个字符“A”或“B”或“C”。另外,插入后可以进行消除。根据输入要求,最多只有100组测试数据,字符串长度不超过100.所以,采取暴力完成题目所给要求。
具体做法
1 将我们可以放置的字符‘ABC’放置在初始字符串的所有位置
2 进行消除操作。
3 消除后的字符串越小,说明我们得到的分数越高。
4 初始字符串长度-消除后的字符串长度,就是我们得到的分数
问题 如何进行字符串的消除操作?
根据题目我们不难分析出来,我们只要将字符串中的相邻的两个或两个以上的相同字符消去,同时得到新的字符串,将新的字符串再进行消除,直到不能消除为止。
所以,我们可以编写一个字符串消除函数,对我们的字符串进行消除工作,直到无法消除为止。
思想:
对字符串进行遍历工作,将所有不能消去的字符存在新的字符串里面。
string Getstr(string& str)
{
inti;
intlen=str.length();//记录字符串长度
if(len<=1)//当长度小于等于1时直接返回其本身
returnstr;
strings;
for(i=0;i+1<len;i++)//循环遍历字符串
{
/*
核心:当发现有相邻的相等的时候,我们再此基础上向后遍历,直到不相等为止
*/
if(str[i]==str[i+1])
{
while(i+1<len&&str[i]==str[i+1])
{
i++;
}
}
elses+=str[i];未发现相等的,将字符储存在新字符串中
}
/*
考虑到最后一个字符就算是无法消去的,在上方也无法加入到新字符串中
所以,对其进行单独考虑。
*/
if(str[len-1]!=str[len-2])
s+=str[len-1];
returns;
}
收获:
(1)STL的应用
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
string Getstr(string& str)
{
inti;
intlen=str.length();
if(len<=1)
returnstr;
strings;
for(i=0;i+1<len;i++)
{
if(str[i]==str[i+1])
{
while(i+1<len&&str[i]==str[i+1])
{
i++;
}
}
elses+=str[i];
}
if(str[len-1]!=str[len-2])
s+=str[len-1];
returns;
}
int main()
{
//freopen("in.txt","r",stdin);
intT;
stringss;
stringstr;
scanf("%d",&T);
intmax,min;
inti,j,le,len;
stringinsert="ABC";
while(T--)
{
cin>>ss;
len=ss.length();
max=len+1;
min=len+1;
for(i=0;i<len;i++)
{
for(j=0;j<3;j++)
{
str=ss.substr(0,i+1)+insert[j]+ss.substr(i+1);
le=str.length();
while(le>((str=Getstr(str)).size()))
{
le=str.size();
}
if(min>le)
min=le;
}
}
printf("%d\n",max-min);
}
return0;
}
substr(n,m): 从字符串中截取出序号n-m的部分,不包括m