题目描述
给定一个由小写字母组成的字符串s,每次你可以删去它的一个非回文子串,
求删成空串的最小次数。
输入输出格式
输入格式:
第一行一个整数 t 表示数据组数。
每组数据第一行一个整数 n表示字符串长度,第二行一个字符串 s
输出格式:
每组数据输出一行一个整数表示答案,如果无法删成空串输出-1
注意:这个题是个坑!是个坑!是个大坑!谁不会去想DP啊,他居然会只特判就能做出来!!!
根据我们精密的数学分析就会发现这个题只会输出 -1, 1 , 2 ,这三个数字(无语==)
特判: 1. -1的情况:ababa || aaaaa || aabaa 没错,就这三种了;
2. 1的情况:不是回文串呗 ==
3. 剩下的都输出2吧!
复杂度 O(n)
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 char s[100005]; 5 int main(){ 6 int t,n; 7 scanf("%d",&t); 8 while(t--){ 9 memset(s,0,sizeof(s)); 10 scanf("%d%s",&n,s); 11 int num=0,i=0,j=n-1,f=0,k=0,m=0; 12 for(int i=0;i<n;i++) if(s[i]==s[i+1]) num++; 13 for(int i=0;i<n;i+=2) if(s[i]==s[i+2]) k++; 14 for(int i=1;i<n;i+=2) if(s[i]==s[i+2]) m++; 15 if(k==(n+1)/2-1&&m==n/2-1&&n%2==1){//判断ababa(必须得是奇数个) 16 printf("-1\n"); 17 continue; 18 } 19 while(i<=j){ 20 if(i==j&&s[i]!=s[i-1]&&num==n-3||n==num+1){//判断aaaaa||aabaa类型 21 printf("-1\n"),f=1; 22 break; 23 } 24 if(s[i]!=s[j]&&i!=j){//不是回文串 25 printf("1\n"),f=1; 26 break; 27 } 28 i++,j--; 29 } 30 if(!f) printf("2\n");//最后就是剩下的了 31 } 32 return 0; 33 }