EOJ 3194 字符串消除
给定一个由大写字母’A’、’B’、’C’构成的字符串s,按如下进行消除过程:
1、字符串s中连续相同字母组成的子串,如果子串的长度大于1,那么这些子串会被同时消除,余下的字符拼成新的字符串。
例如:”ABCCBCCCAA”中”CC”,”CCC”和”AA”会被同时消除,余下”AB”和”B”拼成新的字符串”ABB”。
2、反复进行上述消除,直到新的字符串中相邻字符都不相同为止。
例如:”ABCCBCCCAA”经过一轮消除得到”ABB”,再经过一轮消除得到”A”。
假设在对字符串s消除开始前,允许在s中任意位置(第一个字符之前、最后一个字符之后以及相邻两个字符之间)插入任意一个字符(‘A’,’B’或者’C’),得到字符串t,然后对字符串t经过一系列消除。
请问该如何插入字符,使得字符串t中被消除掉的字符总数(包括插入的字符)最多?
Input
第 1 行:整数 T (1≤T≤10) 为问题数。
第 2 ~ T+1 行:每个问题占一行,每行输入一个由’A’、’B’、’C’组成的字符串s,长度不超过100。
Output
对每个测试数据,首先输出一行问题的编号(0 开始编号,格式:case #0:
等)。在接下来一行中输出被消除掉的最大字符数。
Examples
3
ABCBCCCAA
AAA
ABC
case #0:
9
case #1:
4
case #2:
2
Note
第一组数据:在”ABCBCCCAA”的第2个字符后插入’C’得到”ABCCBCCCAA”,消除后得到”A”,总共消除9个字符(包括插入的’C’)。
1 #include <iostream> 2 #include <string> 3 using namespace std; 4 string x[3] = { "A","B","C" }; 5 void del(int& ans,string tmp) 6 { 7 int len=tmp.size(); 8 while(1) 9 { 10 int flag=0;//判断是否可以继续消除 11 for(string::iterator it=tmp.begin(),t,s;it<tmp.end()-1;)//小心it越界 12 if(*(it+1)==*it) 13 { 14 flag=1; 15 int x=it-tmp.begin();//x记录上次消除位置,以便从后继续消除 16 t=it; 17 while(it<tmp.end()-1&&*(it+1)==*it) it++; 18 tmp.erase(t,it+1); 19 x=x<0?0:x; 20 it=tmp.begin()+x; 21 } 22 else it++; 23 if(flag==0) break; 24 } 25 ans=ans>(len-tmp.size())?ans:len-tmp.size(); 26 } 27 int main() 28 { 29 int T;cin>>T; 30 for(int m=0;m<T;m++) 31 { 32 string s;cin>>s; 33 int ans=0; 34 for(int i=0;i<=s.size();i++) 35 { 36 for(int j=0;j<3;j++) 37 { 38 string tmp=s;tmp.insert(i,x[j]); 39 del(ans,tmp); 40 } 41 } 42 printf("case #%d:\n%d\n",m,ans); 43 44 } 45 return 0; 46 }
在字符串的每个空格(包括首尾)处插入A或B或C,消除连续相同字母组成的字串,判断无可消除字串后退出,经过几次比较,得出消除最多的字符个数。
注意是同时消除,因此应该在消除之后从消除的地方继续向后找字串,而不是从头开始找。
如ABCCBCCCAA,第一次消除CC,CCC,AA,而不是第一次消除得ABBCCCAA,然后继续消除BB,CCC,AAA,这样结果就是全部消除了,这也是我一开始WA的原因。