[ WFU 4th 校赛]Bob的难题

题目

一个字符串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;
} 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值