题目
一个字符串s是由小写英文字母组成。定义一个字符串s′,s′是把s中所有的小写英文字母"a"去掉(其它字母的前后顺序保持不变)。一个新的字符串T,T是由s和s′相连的,换句话说T=s+s′(s必须在s′前面)。
给你一个字符串T,你的任务是寻找一个字符串s满足给定的条件。如果可以找到,它将是唯一的。
注意
本题是拼接,意味着删去所有a后,会出现两个相同的字符串s′的拼接字符串P。本题不是回文题。
思路:
如果T删去a后的字符串P的长度为奇数,明显P不是由两个s’组成,故输出No;
如果为偶数,则需要讨论P是否由两个相同的字符串连接而成,但如果这样讨论会造成后一个字符串Q在T中含有a的可能,这样就不是合法的字符串T,还需要再到T寻找Q。但是不能简单的通过string的查找功能寻找,因为存在T=Q+含a的Q(前合法后非法)的可能,造成找到Q但是T不合法的情况,这种情况很难避免,并且讨论的情况数量过于复杂。
更好的方案是求出s,通过s得到s’,然后s与s’拼接,得到新的字符串D,判断D是否与T相等,这样的思路非常简单。难点在于如何求出s。答案是根据长度提取s。不难看出可以通过删去的a的数量num和字符串P的长度的一半len/2之和就是s的长度lens,而从T取前lens个字符拼成的新字符串就是s;同理,可以用余下的字符拼成s’,但是为了检测T中s’的合法性,我们就需要自己写s’。写法就是将s的非a字符组成新的字符串b。判断T是否与D=a+b相等就能排除前合法后非法的可能。
P的长度len就是T的长度减去a的数量num。
int len=t.length(),num=0;
for(int i=0;i<len;i++){
if(t[i]=='a')num++;
}
int lp=len-num;
事实上由于s可以含a而s’不可以含a造成了s’可以设置非法样例,而s不好设计的情况,即前合法后非法的样例。
#include<bits/stdc++.h>
using namespace std;
int main(){
string t;
freopen("test.txt","r",stdin);
cin>>t;
int len=t.length(),num=0;
for(int i=0;i<len;i++){
if(t[i]=='a')num++;
}
int lp=len-num;
if(lp%2)cout<<":("<<endl;
else{
string s,_s;
int ls=num+lp/2;
for(int i=0;i<ls;i++)
{
s+=t[i];
}
for(int i=0;i<ls;i++)
if(s[i]!='a')_s+=s[i];
if(s+_s==t)cout<<s<<endl;
else cout<<":("<<endl;
}
return 0;
}