• SUFEQPRE


    My blog

    题目简述

    给你一个字符串 SS ,判断有多少个前缀也是后缀

    输入格式

    第一行T,有T组数据 第2~T+1行,T个字符串

    输出格式

    Case (Number): ans

    数据范围

    1<=|S|<=10^6

    Solution

    Step 1:HashStep 1:Hash

    看到这道题很容易想到hash操作,也就是暴力解法,算一算时间是 O(TN) ,显然过不去,但还是写了

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    //#pragma GCC optimize("O2")
    //#pragma GCC optimize("O3")
    //#pragma GCC optimize("Ofast") 加了依然不可做
    using namespace std;
    #define max(a,b) (a>b?a:b)
    unsigned long long hs[1000005],p[1000005];
    int maxn=1,T,cnt,ans;
    char s[1000005];
    int main(){
        while(~scanf("%s", s+1)){
            p[0]=1;
            int n=strlen(s+1);
            for(int i=1;i<=n;i++)hs[i]=hs[i-1]*131+(s[i]-'a'+1);
            for(int i=maxn;i<=n;i++)p[i]=p[i-1]*131;
            ans=0;
            for(int i=1;i<n;i++)
             if(hs[i]==hs[n]-hs[n-i]*p[i])//hash操作
              printf("%d ",i);
            printf("%d
    ",n);
            maxn=max(n,maxn);
        }
    } 

    TLE

    Step 2

    经过深(yi)思(fan)熟(xia)虑(gao)之后,我们发现,最长的公共前后缀是可以确定的,我们只要求出最长的,再左右横跳就可以得到解法了:

    KMP

    利用 KMPKMP 的nxt数组,在 period中的思想类似,可以在 O(N) 的时间而不是 O(3N) ,可以更加高效地解决

    #include<bits/stdc++.h>
    #define max(a,b) (a>b?a:b)
    #pragma GCC optimize("O2")
    #pragma GCC optimize("O3")
    #pragma GCC optimize("Ofast")
    using namespace std;
    int maxn=1,T,cnt,ans;
    char s[1000005];
    int nxt[1000005];
    int main(){
        scanf("%d",&T);
        while(T--){
            scanf("%s", s+1);
            int n=strlen(s+1);
            nxt[1]=0;
            for(int i=2,j=0;i<=n;i++){
                while(j>0&&s[i]!=s[j+1])j=nxt[j];
                if(s[i]==s[j+1])j++;
                nxt[i]=j;
            }
            int ans=0;
            for(int i=n;i;i=nxt[i])++ans;//左右横跳
            printf("Case %d: %d
    ",++cnt,ans-1);//记得长度严格小于N
        }
    } 

     有何意见,请在下方评论谢谢!

  • 相关阅读:
    必懂的wenpack优化
    必懂的webpack高级配置
    webpack基础知识
    vue-cli
    codemirror使用
    js实现二叉树
    react-生命周期
    window 批量修改或去除文件后缀名
    十分钟搞清字符集和字符编码
    php判断一个值是否在一个数组中,区分大小写-也可以判断是否在键中
  • 原文地址:https://www.cnblogs.com/coder-cjh/p/11410867.html
Copyright © 2020-2023  润新知