[2018.07.10 T2]不回文

暂无链接

不回文

【问题描述】

学不会最小回文串划分的豆豆决定弃疗选择挑战非回文划分。

他想知道一个字符串 S 的最少和最多能划分成几个非回文串?

注: 如果一个字符串不是回文串,那么他是非回文串。例如()()是非回文串,而 ())(是回文串。

【输入格式】

第一行一个整数 T,表示测试数据组数。

接下来 T 行,每行一个仅由小写字母构成的字符串 S。

【输出格式】

输出 T 行,每行两个整数分别表示最小和最大划分。如果不存在非合法划分输出“-1 -1” (不含分号)。

【输入样例】

3
aaa
abba
abcb

【输出样例】

-1 -1
2 2
1 2

【数据范围】
      测试点编号                    数据范围                        约定 

           1                    |S |<=10                无特殊约定 

           2                                         只有 ab 两种字母 
                              |S |<=1,000 
           3                                            无特殊约定 

           4 
                                                     只有 ab 两种字母 
           5                  |S |<=30,000 

           6                                            无特殊约定 

           7 
                             |S |<=300,000           只有 ab 两种字母 
           8 

           9 
                             |S |<=300,000              无特殊约定 
          10 

对于所有数据满足,T=10。

题解

O ( n 2 ) d p 没写,梦想 T 3 去了,打完 10 走人,结果最暴力的 10 分还 T 了, s h t

扫描二维码关注公众号,回复: 2119136 查看本文章

最后的结论太玄学了,能想到算我输, o r z 考场切题的 R o c k d u ,太强了 % % %

首先来看看最小值(貌似最小值是雅礼的签到题,但是我没去啊??? s h t !),最小划分只有三种情况:

1.该串本身不回文,那么最小划分就是这个串,答案 = 1

2.该串可以被分成 2 个不回文的串,此时答案 = 2

3.若前面的条件都不满足,则不存在合法划分。

证明???看看题解怎么说:

图片2.png

再说最大值,我们可以先粗略的贪心一波:如果相邻的两个字符不相同,我们就可以把这两个字符单独划分出来(最后一个多余的字符忽略掉),这样我们求出来的答案将会是一个上限,什么时候这个答案是错的呢???,如下:

j a j b j c j d j e j f j p j o j k j

按照贪心的划分,最后会留下一个长度为 3 的回文串,如下:

j a   |   j b   |   j c   |   j d   |   j e   |   j f   |   j p   |   j o   |   j k j

所以只能合并一下中间的串:

j a   |   j b   |   j c   |   j d j e j   |   f j   |   p j   |   o j   |   k j

这样我们的最大划分就会 1

上面的合并也有一点问题,当串本身不能被划分为两个不回文串的时候,最大划分为 1 ,需要特判。

代码
#include<bits/stdc++.h>
using namespace std;
const int M=3e5+5;
int T,len,base=19491001,minn,maxn,flag,cut,i;
char ch[M];
unsigned long long key[M],abc[M],cba[M];
void in(){scanf("%s",ch+1);}
bool bhw(int l,int r){return abc[r]-abc[l-1]*key[r-l+1]!=cba[l]-cba[r+1]*key[r-l+1];}
void ac()
{
    len=strlen(ch+1),abc[0]=cba[len+1]=maxn=flag=cut=0,minn=-1;
    for(i=1;i<=len;++i)abc[i]=abc[i-1]*base+ch[i];
    for(i=len;i>=1;--i)cba[i]=cba[i+1]*base+ch[i];
    for(i=1;i<len;++i)if(bhw(1,i)&&bhw(i+1,len)){minn=2;cut=1;break;}
    if(bhw(1,len))minn=1;else if(cut)minn=2;else {puts("-1 -1");return;}
    for(i=1;i<=len;++i)if(!flag)flag=1;else if(ch[i]!=ch[i-1])flag=0,++maxn;
    if(len>=3&&len%2)
    {
        flag=1;
        for(i=1;i<=len;i+=2)if(ch[i]!=ch[1]){flag=0;break;}
        for(i=2;i<=len;i+=2)if(ch[i]==ch[1]){flag=0;break;}
        if(flag)--maxn;
    }
    printf("%d %d\n",minn,cut?maxn:1);
}
int main()
{
    scanf("%d",&T);
    key[0]=1;for(i=1;i<M;++i)key[i]=key[i-1]*base;
    while(T--)in(),ac();
}

猜你喜欢

转载自blog.csdn.net/shadypi/article/details/81004453
T2
今日推荐