zoukankan      html  css  js  c++  java
  • HDU

    http://acm.hdu.edu.cn/showproblem.php?pid=5340

    题意

    判断是否能将字符串S分成三段非空回文串

    分析

    manacher预处理出前缀和后缀回文的位置, 枚举第一个回文串和第三个回文串,这样得到第二个回文串的区间,找中点,因为manacher处理后所有的回文串长度都是奇数,然后根据中点的回文半径判断中间部分是否回文即可, 复杂度o(n2)。至于n2复杂度为什么能水过去。。不是很懂

    #include<iostream>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #include<vector>
    #include<cstdio>
    #include<algorithm>
    #include<map>
    #include<set>
    #define rep(i,e) for(int i=0;i<(e);i++)
    #define rep1(i,e) for(int i=1;i<=(e);i++)
    #define repx(i,x,e) for(int i=(x);i<=(e);i++)
    #define X first
    #define Y second
    #define PB push_back
    #define MP make_pair
    #define mset(var,val) memset(var,val,sizeof(var))
    #define scd(a) scanf("%d",&a)
    #define scdd(a,b) scanf("%d%d",&a,&b)
    #define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
    #define pd(a) printf("%d
    ",a)
    #define scl(a) scanf("%lld",&a)
    #define scll(a,b) scanf("%lld%lld",&a,&b)
    #define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
    #define IOS ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    typedef long long ll;
    template <class T>
    void test(T a){cout<<a<<endl;}
    template <class T,class T2>
    void test(T a,T2 b){cout<<a<<" "<<b<<endl;}
    template <class T,class T2,class T3>
    void test(T a,T2 b,T3 c){cout<<a<<" "<<b<<" "<<c<<endl;}
    const int N = 1e6+10;
    //const int MAXN = 210;
    const int inf = 0x3f3f3f3f;
    const ll INF = 0x3f3f3f3f3f3f3f3fll;
    const ll mod = 200907;
    int T;
    void testcase(){
        printf("Case #%d: ",++T);
    }
    const int MAXN = 4e4+5;
    const int MAXM = 30;
    char ma[MAXN],s[MAXN];
    int mp[MAXN];
    int pre[MAXN],suf[MAXN];
    void Manacher(int len){
        int l=0;
        ma[l++]='$';
        ma[l++]='#';
        for(int i=0;i<len;i++) ma[l++]=s[i],ma[l++]='#';
        ma[l]=0;
        int mx=0,id=0;
        for(int i=0;i<l;i++){
            mp[i]=mx>i?min(mp[2*id-i],mx-i):1;
            while(ma[i+mp[i]]==ma[i-mp[i]]) mp[i]++;
            if(i+mp[i]>mx){
                mx=i+mp[i];
                id=i;
            }
        }
    }
    int main() {
    #ifdef LOCAL
        freopen("in.txt","r",stdin);
    #endif // LOCAL
        int t;
        scd(t);
        while(t--){
            scanf("%s",s);
            int len = strlen(s);
            Manacher(len);
            int l=0,r=0;
            len=2*len+1;
            for(int i=1;i<=len;i++){
                if(mp[i]==i&&i!=1) pre[l++]=mp[i];
            //mp[i]==i保证mp[i]可以作为第一个回文串的半径,加入pre数组,i!=1保证第一个回文串不为空
                if(mp[i]+i-1==len&&i!=len) suf[r++]=mp[i];
            }
            int i,j;
            for(i=l-1;i>=0;i--){
                for(j=0;j<r;j++){
                    int t1=2*pre[i];
                    int t2=len+1-2*suf[j];
                    int tmp = (t1+t2)>>1;
                    if(t1>t2) continue;
                    if(mp[tmp]==1) continue;
                    if(mp[tmp]*2-1>=t2-t1+1) break;
                }
                if(j<r) break;
            }
            if(i>=0) puts("Yes");
            else puts("No");
        }
        return 0;
    }
            
  • 相关阅读:
    2C Numerical Sequence (hard version)
    2A Subset——折半枚举+二分
    假设检验、Z检验与T检验
    使用PyCaret构建机器学习模型
    Python图像处理
    NumPy教程
    NLP中的标识化
    概率论的数学基础
    用直方图和箱线图理解数据
    神经网络简易教程
  • 原文地址:https://www.cnblogs.com/fht-litost/p/9293344.html
Copyright © 2011-2022 走看看