hihocoder#1039 解题报告

 

题目描述

#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'),得到字符串tt经过一系列消除后,小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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值