hdu2087 剪花布条(kmp基础变形)

来源:互联网 发布:互普威盾阻止软件安装 编辑:程序博客网 时间:2024/05/22 05:54

题目:

一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案。对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢?

分析:

唯一需要注意的是,比如aaaa中找aa,答案是2而并非3。也就是说,找到的子串是不能重叠的。
只需要修改kmp找子串的函数即可,当找到一个后,下次子串直接从0开始,而不是next[j-1]

代码:

#include <iostream>#include <algorithm>#include <queue>#include <stack>#include <vector>#include <map>#include <set>#include <cmath>#include <cstdlib>#include <cstring>#include <cstdio>using namespace std;#define ms(a,b) memset(a,b,sizeof(a))#define lson rt*2,l,(l+r)/2#define rson rt*2+1,(l+r)/2+1,rtypedef unsigned long long ull;typedef long long ll;const int MAXN=1005;const double EPS=1e-8;const int INF=0x3f3f3f3f;int m,n,nxt[MAXN];char s[MAXN],t[MAXN];void getnext(){    nxt[0] = 0;    for(int i=1;i<n;i++){        int j = nxt[i-1];        while(t[j] != t[i] && j>0){            j = nxt[j-1];        }        if(t[j] == t[i])    nxt[i] = j + 1;        else    nxt[i] = 0;    }}int kmp(){    int j = 0,ans = 0;    for(int i=0;i<m;i++){        while(t[j] != s[i] && j>0){            j = nxt[j-1];        }        if(t[j] == s[i])    j++;        if(j>=n){            ans ++;            j =0;        }    }    return ans;}int main(){    while(scanf("%s",s)){        if(s[0] == '#') break;        scanf("%s",t);        m = strlen(s);        n = strlen(t);        getnext();        printf("%d\n",kmp());    }    return 0;}
原创粉丝点击