csp信奥赛C++高频考点专项训练之字符串 --【回文字符串】:回文拼接

题目描述
一个字符串是回文串,当且仅当该字符串从前往后读和从后往前读是一样的,例如, aabaa \texttt{aabaa} aabaa 和 ccddcc \texttt{ccddcc} ccddcc 都是回文串,但 abcd \texttt{abcd} abcd 不是。
小杨有 n n n 个仅包含小写字母的字符串,他想请你编写程序判断每个字符串是否由两个长度至少为 2 2 2 的回文串前后拼接而成。
输入格式
第一行包含一个正整数 n n n,代表字符串数量。
接下来 n n n 行,每行一个仅包含小写字母的字符串。
输出格式
对于每个字符串输出一行,如果该字符串由两个长度至少为 2 2 2 的回文串前后拼接而成则输出 Yes,否则输出 No。
输入输出样例 1
输入 1
4
abcd
aabbb
aaac
abcdd
输出 1
No
Yes
No
No
说明/提示
样例 1 解释
对于第 1 , 3 , 4 1,3,4 1,3,4 个字符串,都不是由两个长度至少为 2 2 2 的回文串前后拼接而成。
第 2 2 2 个字符串由回文串 aa \texttt{aa} aa 和 bbb \texttt{bbb} bbb 前后拼接而成,并且两个回文串长度都至少为 2 2 2。
数据规模与约定
对全部的测试数据,保证 1 ≤ n ≤ 10 1 \leq n \leq 10 1≤n≤10,且每个字符串的长度均不超过 100 100 100。
分析思路
题目要求判断一个字符串是否能被分割成两个长度均至少为 2 的回文子串(前后拼接)。
因为字符串长度不超过 100,可以直接暴力枚举所有可能的分割点。
分割点 i 表示前一部分的长度(即前 i 个字符),要求 2 ≤ i ≤ len-2(后一部分长度至少为 2)。
对于每个分割点,分别检查前部分 [0, i-1] 和后部分 [i, len-1] 是否为回文串。
如果存在任何一个分割点满足条件,输出 Yes,否则输出 No。
检查回文串采用双指针法,时间复杂度 O(len),总时间复杂度 O(n * len²),完全可行。
代码实现
cpp
#include <bits/stdc++.h>
using namespace std;
// 判断字符串 s 中区间 [l, r] 是否为回文串
bool check(string s, int l, int r) {
while (l < r) { // 双指针,从两端向中间比较
if (s[l] != s[r]) return false; // 发现不同字符,不是回文
l++; r--; // 移动指针继续比较
}
return true; // 全部相同,是回文串
}
int main() {
int n; // 字符串个数
cin >> n; // 读入 n
while (n--) { // 循环处理每个字符串
string s;// 当前字符串
cin >> s; // 读入字符串
int len = s.size(); // 字符串长度
bool ok = false; // 标记是否找到合法分割
// 枚举分割点 i 表示前部分长度,范围 2 ~ len-2(前后长度至少为2)
for (int i = 2; i <= len - 2; ++i) {
// 检查前部分 [0, i-1] 和后部分 [i, len-1] 是否都是回文
if (check(s, 0, i-1) && check(s, i, len-1)) {
ok = true; // 找到合法分割
break; // 无需继续枚举
}
}
// 根据结果输出 Yes 或 No
cout << (ok ? "Yes" : "No") << '\n';
}
return 0;
}
功能分析
-
功能:对输入的每个字符串,判断它是否能由两个长度至少为 2 的回文串前后拼接而成。
-
实现方式:暴力枚举所有可能的分割点(前部分长度从 2 到总长度减 2),对每个分割点调用回文判断函数检查前后两部分。回文判断使用双指针法,从两端向中间比较字符。
-
时间复杂度 :每个字符串长度
L ≤ 100,分割点最多L-3个,每个分割点做两次回文判断,每次 O(L),故单串最坏 O(L²) ≈ 10⁴ 次操作,总 n ≤ 10,完全可在 1 秒内完成。 -
空间复杂度:仅使用了常数个变量,O(1) 额外空间。
【完整系列请查看专栏】:
信奥赛C++普及组CSP-J一等奖通关刷题题单及题解:
https://blog.csdn.net/weixin_66461496/category_12673810.html 点击跳转
各种学习资料,助力大家一站式学习和提升!!!
cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
cout<<"########## 一站式掌握信奥赛知识! ##########";
cout<<"############# 冲刺信奥赛拿奖! #############";
cout<<"###### 课程购买后永久学习,不受限制! ######";
return 0;
}
【秘籍汇总】(完整csp信奥赛C++学习资料):
1、csp/信奥赛C++,完整信奥赛系列课程(永久学习):
https://edu.csdn.net/lecturer/7901 点击跳转

2、CSP信奥赛C++竞赛拿奖视频课:
https://edu.csdn.net/course/detail/40437 点击跳转

https://edu.csdn.net/course/detail/41081 点击跳转

3、csp信奥赛高频考点知识详解及案例实践:
CSP信奥赛C++动态规划:
https://blog.csdn.net/weixin_66461496/category_13096895.html点击跳转
CSP信奥赛C++标准模板库STL:
https://blog.csdn.net/weixin_66461496/category_13108077.html 点击跳转
信奥赛C++提高组csp-s知识详解及案例实践:
https://blog.csdn.net/weixin_66461496/category_13113932.html 点击跳转
4、csp信奥赛冲刺一等奖有效刷题题解:
信奥赛C++普及组CSP-J一等奖通关刷题题单及题解:
https://blog.csdn.net/weixin_66461496/category_12673810.html 点击跳转
信奥赛C++提高组csp-j初赛&复赛真题题解(持续更新): https://blog.csdn.net/weixin_66461496/category_12808781.html 点击跳转
信奥赛C++提高组csp-s初赛&复赛真题题解(持续更新):
https://blog.csdn.net/weixin_66461496/category_13125089.html 点击跳转
5、GESP C++考级真题题解:

GESP(C++ 一级+二级+三级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12858102.html 点击跳转

GESP(C++ 四级+五级+六级)真题题解(持续更新):https://blog.csdn.net/weixin_66461496/category_12869848.html 点击跳转

GESP(C++ 七级+八级)真题题解(持续更新):
https://blog.csdn.net/weixin_66461496/category_13117178.html 点击跳转
· 文末祝福 ·
cpp
#include<bits/stdc++.h>
using namespace std;
int main(){
cout<<"跟着王老师一起学习信奥赛C++";
cout<<" 成就更好的自己! ";
cout<<" csp信奥赛一等奖属于你! ";
return 0;
}