【NKOJ 1505】 何老板的考古发现

来源:互联网 发布:手机淘宝店标怎么设置 编辑:程序博客网 时间:2024/04/29 15:12

链接

原题地址

思路

把环展开,变成长度为两倍的链,暴力KMP匹配每两个串。

代码

#include <iostream>#include <cstdio>#include <cstring>using namespace std;char ch[110][20010];int f[110][10010], g[20010], ok[110];int n, m, cnt;void get_f(){    for(int i = 1; i <= n; i ++){        int p = 0;        for(int j = 2; j <= m; j ++){            while(p && ch[i][j] != ch[i][p+1]) p = f[i][p];            if(ch[i][j] == ch[i][p+1]) p ++;            f[i][j] = p;        }    }}bool kmp(int x, int y){    int p = 0;    for(int i = 1; i <= 2*m; i ++){        while(p && ch[x][i] != ch[y][p+1]) p = f[y][p];        if(ch[x][i] == ch[y][p+1]) p ++;        if(p == m) return true;    }    return false;}void add_ok(int x){    for(int i = 1; i <= m; i ++) ch[x][i+m] = ch[x][i];    ok[++cnt] = x;}int main(){    scanf("%d%d", &n, &m);    for(int i = 1; i <= n; i ++) scanf("%s", ch[i]+1);    get_f();add_ok(1);    for(int i = 2, is = 1; i <= n; i ++, is = 1){        for(int j = 1; j <= cnt; j ++)            if(kmp(ok[j],i) == 1){is = 0;break;}        if(is) add_ok(i);    }    printf("%d", cnt);    return 0;}
1 0
原创粉丝点击