题解:B4101 [CSP-X2023 山东] 回文字符串

· · 题解

B4101 题目传送门

可以利用双指针的思想

设立指针 L 从左到右移动遍历字符串 sR 从右到左移动,直到, L\geq R 则:

注意一点:

当判断构造的两个子串 slsr 是否满足互为回文的条件时,只需要判断两个子串是否相等,因为已知了此时 s[L]\neq s[R],所以两个字符串无法在相对位置回文。

参考代码

#include <bits/stdc++.h>
#define int long long
using namespace std;
string s;
int ans;
signed main() {
    //freopen("palindrome.in","r",stdin);
    //freopen("palindrom.out","w",stdout);
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
  //如果你用cin,建议关闭同步流增加效率
    cin>>s;
    int l=0,r=s.size()-1;
    while(l<r){
        if(s[l]==s[r]){
            ans+=2;
            l++;r--;//继续遍历
            if(l==r) ans++;//如果再遍历一步后,L和R正好重合,那么此时又能创造一个大字符串,所以ans再加一
        }
        else{
            string sl,sr;
            while(l<r){
                sl+=s[l++];
                sr=s[r--]+sr;//给子串拼接新遍历的字符
                if(sl==sr) break;//判断是否互为回文
            }
            if(sl!=sr){
                ans++;    //不回文,增加一个
            }
            else ans+=2;//回文,增加两个
        }
    }
    if(ans<=1){
        cout<<"NO\n";
    }//如果到最后只有一个串满足,那就是大串自己,所以输出 NO
    else{
        cout<<"YES\n"<<ans<<"\n";
    }//否则,大串满足条件,再输出能分割成的子串数 ans
    return 0;
    //完结撒花
}

这是小蒟蒻的第一篇题解,可以给个赞吗%%