Part 0 前言
这是一道思考难度比较大的题,我前后改了七次才过,特此纪念。
Part 1 思路
先读题,题意大致为给定一个字符串,能在字符串的前面添加数个 l
,q
,b
三个字符,问能不能构成回文字符串。
我们可以将原字符串(长度为 l e n len len)分为三段:
第一段,只包含题目中给出的三个特殊字符且在原字符串的最前方的字串,设长度为 l e n 1 len1 len1。
第二段,只包含题目中给出的三个特殊字符且在原字符串的最后方的字串,设长度为 l e n 2 len2 len2。
第三段,第二段和第一段之间的子串,设长度为 l e n 3 len3 len3。
例如字符串 lqbkkklqbkkklqb
,第一段为 lqb
,长度为
3
3
3;第二段为 kkklqbkkk
,长度为
9
9
9;第三段为 lqb
,长度为
3
3
3。
分情况讨论,若
l
e
n
1
≤
l
e
n
2
len1 \leq len2
len1≤len2,那么从
0
0
0 开始,遍历到
l
e
n
−
l
e
n
2
+
l
e
n
1
−
1
len-len2+len1-1
len−len2+len1−1,判断这个区间内是否回文,若回文,则答案为 Yes
,否则答案为 No
。
若
l
e
n
1
>
l
e
n
2
len1 > len2
len1>len2,那么可以证得,永远不可能回文,答案为 No
。
Part 2 AC code
#include<bits/stdc++.h>
using namespace std;
string s;
int len;
int get_len_front(){
int sum=0;
for(int i=0;i<len;i++){
if(s[i]=='l'||s[i]=='q'||s[i]=='b') sum++;
else break;
}
return sum;
}//获取len1
int get_len_back(){
int sum=0;
for(int i=len-1;i>=0;i--){
if(s[i]=='l'||s[i]=='q'||s[i]=='b') sum++;
else break;
}
return sum;
}//获取len2
int main(){
int t;
cin>>t;
while(t--){
cin>>s;
len=s.length();
int len1=get_len_front();
int len2=get_len_back();
if(len1==len2&&len1==len){
cout<<"Yes\n";
continue;
}//若整个字符串都为特殊字符,那么将原串倒序拼在前面即可,所以答案为Yes
int bj=1;
if(len1<=len2){
for(int i=0;i<len-len2+len1-1;i++){
if(s[i]!=s[len-len2+len1-1-i]){
cout<<"No\n";bj=0;break;
}//判断是否回文
}
if(bj) cout<<"Yes\n";
}
else
{
cout<<"No\n";
}
}
}