zoukankan      html  css  js  c++  java
  • 【字符串KMP】一些题?

    POJ 2752  NameFame

    利用失配数组nxt
    最长的一个“前后缀”是1~nxt[n],那么下一个是多少?
    #include<bits/stdc++.h>
    using namespace std;
    #define rg register
    const int N=1000000+5,M=10000+5,inf=0x3f3f3f3f,P=99999997;
    int l,j,cnt,nxt[N],ans[N];
    char s[N];
    int main(){
    //    freopen("in2.txt","r",stdin);
        while(scanf("%s",s+1)==1){
            memset(nxt,0,sizeof(nxt));
            l=strlen(s+1),j=cnt=0;
            for(int i=2;i<=l;++i){
                while(j&&s[i]!=s[j+1]) j=nxt[j];
                if(s[i]==s[j+1]) ++j;
                nxt[i]=j;
            }
            int pos=l;
            while(nxt[pos])
                ans[++cnt]=nxt[pos],pos=nxt[pos];
            for(int i=cnt;i;--i) printf("%d ",ans[i]);
            printf("%d
    ",l);
        }
        return 0;
    }

    Power String 循环节

    给定一个字符串,求它最短的循环节长度
    考虑n-next[n]与n的关系
    若n不是n-next[n]的倍数,如何证明最短循环节长度只能是1
    假设S的长度为len,则S存在最小循环节,循环节的长度L为len-next[len],子串为S[0…len-next[len]-1]。

    (1)如果len可以被len - next[len]整除,则表明字符串S可以完全由循环节循环组成,循环周期T=len/L。

    (2)如果不能,说明还需要再添加几个字母才能补全。需要补的个数是循环个数L-len%L=L-(len-L)%L=L-next[len]%L,L=len-next[len]。

    #include <cstdio>
    #include <iostream>
    #include <string>
    #include <cstring>
    using namespace std;
    #define rg register
    const int N=1000000+5,M=10000+5,inf=0x3f3f3f3f,P=99999997;
    int T,n,l,j,nxt[N],ans[N];
    char s[N];
    int main(){
    //    freopen("in2.txt","r",stdin);
        scanf("%d",&T);
        while(scanf("%s",s+1)==1&&s[1]!='.'){
            memset(nxt,0,sizeof(nxt));
            n=strlen(s+1),j=0;
            for(int i=2;i<=n;++i){
                while(j&&s[j+1]!=s[i]) j=nxt[j];
                if(s[i]==s[j+1]) ++j;
                nxt[i]=j;
            }
            l=n-nxt[n];
            if(n%l) puts("1");
            else printf("%d
    ",n/l);
        }
        return 0;
    }

    POJ - 2185 Milking Grid

    给定一个R*C的二维矩阵,其中C<= 75,求面积最小的长方形生成单元
    例如:ABABA
    ABABA 
    则答案为2,即AB
    思路:
    对每一维分别做一次KMP,在做这一维时,将另一维整体看成字符
    一维情况下,答案是n-next[n]
    二维情况下,答案是(R-next[R])*(C-next[C])
    #include <cstdio>
    #include <iostream>
    #include <string>
    #include <cstring>
    using namespace std;
    #define Max(x,y) (x)>(y)?(x):(y)
    #define Min(x,y) (x)>(y)?(y):(x)
    #define ll long long
    #define rg register
    const int N=10000+5,M=10000+5,inf=0x3f3f3f3f,P=99999997;
    int r,c,w=0,h=0,nxt[N],ans[N];
    char s[N][N];
    
    int KMP(int pos,int flag){
        memset(nxt,0,sizeof(nxt));
        int j=0,l;
        if(!flag){
            for(int i=2;i<=c;++i){
                while(j&&s[pos][j+1]!=s[pos][i]) j=nxt[j];
                if(s[pos][i]==s[pos][j+1]) ++j;
                nxt[i]=j;
            }
            return c-nxt[c];
        }
        else{
            for(int i=2;i<=r;++i){
                while(j&&s[j+1][pos]!=s[i][pos]) j=nxt[j];
                if(s[i][pos]==s[j+1][pos]) ++j;
                nxt[i]=j;
            }
            return r-nxt[r];
        }
    }
    
    int main(){
    //    freopen("in2.txt","r",stdin);
        scanf("%d%d",&r,&c);
        for(int i=1;i<=r;++i) scanf("%s",s[i]+1);
        for(int i=1;i<=r;++i) w=Max(w,KMP(i,0));
        for(int i=1;i<=c;++i) h=Max(h,KMP(i,1));
        printf("%d
    ",w*h);
        return 0;
    }
  • 相关阅读:
    application.properties /application.yml官网查看配置;springboot application.properties 官网查看,info yml 查看;springboot.yml查看info;springboot.yml查看Actuator监控中心info
    Clion 教程书写Hello World,C语言开发;Clion 的C语言开发
    Host is not allowed to connect to this MySQL server---------------->windows10
    @RequestBody jackson解析复杂的传入值的一个坑;jackson解析迭代数组;jackson多重数组;jakson数组
    windows10 搭建Dubbo
    无DNS解析环境下部署Vcenter6.7
    常用联想网络连接
    Linux 不重启扫描存储磁盘
    WWN,WWNN,WWPN三者的区别
    HDFS、Ceph、GFS、GPFS、Swift 等分布式存储技术的特点和适用场景
  • 原文地址:https://www.cnblogs.com/lxyyyy/p/11253164.html
Copyright © 2011-2022 走看看