切割回文

1|0题目描述

阿福最近对回文串产生了非常浓厚的兴趣。

如果一个字符串从左往右看和从右往左看完全相同的话,那么就认为这个串是一个回文串。例如,abcaacba 是一个回文串,abcaaba 则不是一个回文串。

阿福现在强迫症发作,看到什么字符串都想要把它变成回文的。阿福可以通过切割字符串,使得切割完之后得到的子串都是回文的。

现在阿福想知道他最少切割多少次就可以达到目的。例如,对于字符串 abaacca,最少切割一次,就可以得到 abaacca 这两个回文子串。

2|0输入

输入的第一行是一个整数 TTT (T≤20)(T \le 20)(T20) ,表示一共有 TTT 组数据。 接下来的 TTT 行,每一行都包含了一个长度不超过的 100010001000 的字符串,且字符串只包含了小写字母。

3|0输出

对于每组数据,输出一行。该行包含一个整数,表示阿福最少切割的次数,使得切割完得到的子串都是回文的。

4|0输入输出样例

4|1样例输入 #1

3 abaacca abcd abcba

4|2样例输出 #1

1 3 0

5|0提示

对于第一组样例,阿福最少切割 111 次,将原串切割为 abaacca 两个回文子串。

对于第二组样例,阿福最少切割 333 次,将原串切割为 abcd 这四个回文子串。

对于第三组样例,阿福不需要切割,原串本身就是一个回文串。

复制代码
#include<bits/stdc++.h> using namespace std; const int N=1e5+10; int f[N],a[N],n,res,m,t; bool vis[1010][1010]; string s; bool check(int st,int ed)//用于判断是不是回文串 { while(st<=ed){ if(s[st]==s[ed]) st++,ed--; else return false; } return true; } int main() { cin>>t; while(t--) { memset(f,1,sizeof f);//因为要求最小值,所以先初始化为最大 memset(vis,false,sizeof vis); cin>>s; res=s.size(); for(int i=0;i<res;i++) for(int j=i+1;j<res;j++) if(check(i,j)) vis[i][j]=true;//判断每个片段是否是回文串 f[1]=0;//第一个字符不需要切割也是,所以为0 for(int i=2;i<=res;i++) { if(vis[0][i-1]) f[i]=0;//如果在这之前的是回文串那么从这个点开始就不需要切割 else f[i]=f[i-1]+1;//否则+1,继续切割 for(int j=i;j>=1;j--) if(vis[j-1][i-1]) f[i]=min(f[i],f[j-1]+1);//然后从这之前再判断,有可能前面存在f=0,更新状态 } cout<<f[res]<<endl; } return 0; }
复制代码

 


__EOF__

本文作者Sakurajimamai
本文链接https://www.cnblogs.com/o-Sakurajimamai-o/p/17470820.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   o-Sakurajimamai-o  阅读(29)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
-- --
点击右上角即可分享
微信分享提示