[kuangbin带你飞]专题十六 KMP & 扩展KMP & ManacherC - 剪花布条 HDU - 2087 (kmp不覆盖匹配)

C - 剪花布条 HDU - 2087

题目连接:https://vjudge.net/contest/70325#problem/C

题目:

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

Input输入中含有一些数据,分别是成对出现的花布条和小饰条,其布条都是用可见ASCII字符表示的,可见的ASCII字符有多少个,布条的花纹也有多少种花样。花纹条和小饰条不会超过1000个字符长。如果遇见#字符,则不再进行工作。
Output输出能从花纹布中剪出的最多小饰条个数,如果一块都没有,那就老老实实输出0,每个结果之间应换行。
Sample Input
abcde a3
aaaaaa  aa
#
Sample Output
0
3
思路:求不覆盖的kmp,只要把当j==模式串长度时,后面的j==0即可,这样又重新开始从0开始,一满足长度为模式串时,ans就加一

//
// Created by HJYL on 2019/8/15.
//
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <queue>
#include <stack>
#include <set>
#include <algorithm>

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
using namespace std;
typedef long long ll;
const int maxn=1e6+10;
char str[maxn],str1[maxn];
int nextt[maxn];
void getnext()
{
    int i=0,j=-1;
    int n=strlen(str1);
    nextt[0]=-1;
    while(i<n)
    {
        if(j==-1||str1[i]==str1[j])
        {
            ++i,++j;
            if(str1[i]!=str1[j])
                nextt[i]=j;
            else
                nextt[i]=nextt[j];
        } else
            j=nextt[j];
    }
}
int kmp()
{
    int i=0,j=0;
    int ans=0;
    int m=strlen(str);
    int n=strlen(str1);
    while(i<m)
    {
        if(j==-1||str[i]==str1[j])
        {
            i++,j++;
        } else
            j=nextt[j];
        if(j==n)
            j=0,ans++;
    }
    return ans;
}
int main()
{
    while(~scanf("%s",str))
    {
        if(str[0]=='#')
            break;
        scanf("%s",str1);
        getnext();
        printf("%d\n",kmp());
    }
    return 0;
}

 

 
posted @ 2019-08-15 13:09  branna  阅读(126)  评论(0编辑  收藏  举报