CodeForces 113B Petr#(KMP + 字符串hash)

题目链接

分析:这题用hash来判重效率不错。可以先用KMP预处理出所有起点和终点,从每个起点出发,向后hash ,遇到终点就判断字符串是否出现过(若么出现过就ans+1),否则跳过。。

参考代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;

const int maxn = 2050;
char T[maxn],Beg[maxn],End[maxn];
int fail[2][maxn] , pos[2][maxn];
int len0 , len1 ,lenT ,ans;

const int max_hash = 10000007;
const int B[2]={100007,999997};
struct HASH{
    int flag[max_hash];
    int record[max_hash];
    void init(){
        memset(flag,0,sizeof(flag));
        memset(record,-1,sizeof(record));
    }
    void solve(){
        ans = 0;
        for(int i=0;i<lenT;i++) if(pos[0][i]) {
            long long p=0 , q=0;
            int M = i+max(len0,len1)-1;
            for(int j=i;j<M;j++){
                p=(p*B[0]+T[j]-'a'+1)%max_hash;
                q=(q*B[1]+T[j]-'a'+1)%max_hash;
            }
            for(int j=M;j<lenT;j++){
                p=(p*B[0]+T[j]-'a'+1)%max_hash;
                q=(q*B[1]+T[j]-'a'+1)%max_hash;
                if(pos[1][j-len1+1]){
                    int x = p;
                    while(flag[x] && record[x]!=q) x=(x+1)%max_hash;
                    if(!(flag[x] && record[x]==q)) {
                        ans++;
                        flag[x]=1 , record[x]=q;
                    }
                }
            }
        }
    }
};
HASH hs;

void get_fail(char *p,int *f){
    int m = strlen(p);
    f[0] = f[1] = 0;
    int j=0;
    for(int i=1;i<m;i++){
        j = f[i];
        while(j && p[j]!=p[i]) j = f[j];
        f[i+1] = p[i]==p[j] ? j+1 : 0;
    }
}
void kmp_match(char *T,char *p,int *f,int *pos){
    memset(pos,0,sizeof(pos));

    int n = lenT , m=strlen(p);
    int j = 0;
    for(int i=0;i<n;i++){
        while(j && T[i]!=p[j]) j=f[j];
        if(T[i]==p[j]) j++;
        if(j==m) pos[i-m+1] = 1;
    }
}

int main()
{
    //hs.init();

    scanf("%s%s%s",T,Beg,End);
    len0 = strlen(Beg) , len1 = strlen(End) ,lenT = strlen(T);

    get_fail(Beg,fail[0]) , get_fail(End,fail[1]);
    kmp_match(T,Beg,fail[0],pos[0]);
    kmp_match(T,End,fail[1],pos[1]);
    hs.solve();

    printf("%d\n",ans);
    return 0;
}
    原文作者:KMP算法
    原文地址: https://blog.csdn.net/lg_csu/article/details/17016079
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞