HDU2087 剪花布条 [KMP]

剪花布条
Time Limit: 1000MS
Memory Limit: 32768KB
64bit IO Format: %I64d & %I64u

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

Input
输入中含有一些数据,分别是成对出现的花布条和小饰条,其布条都是用可见ASCII字符表示的,可见的ASCII字符有多少个,布条的花纹也有多少种花样。花纹条和小饰条不会超过1000个字符长。如果遇见#字符,则不再进行工作。

Output
输出能从花纹布中剪出的最多小饰条个数,如果一块都没有,那就老老实实输出0,每个结果之间应换行。

Sample Input
abcde a3
aaaaaa aa
#

Sample Output
0
3


KMP裸题。。。
注意get_fail的时候递推边界 fail[1] = 0 ,所以应该从pos = 1 开始推着走

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<iomanip>
#include<ctime>
#include<climits>
#include<cctype>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
#define smax(x,tmp) x=max((x),(tmp))
#define smin(x,tmp) x=min((x),(tmp))
#define maxx(x1,x2,x3) max(max(x1,x2),x3)
#define minn(x1,x2,x3) min(min(x1,x2),x3)
const int INF=0x3f3f3f3f;
const int maxn = 1005;
int fail[maxn];
char s[maxn],ss[maxn];
void get_fail(char s[],int lens)
{
    fail[0] = 0 , fail[1] = 0;
    int pos = 1; // must start from 1 !! or dead loop !!
    while(pos<lens)
    {
        int root = fail[pos];
        while(root && s[root]!=s[pos]) root = fail[root];
        fail[pos+1] = s[root]==s[pos]? root+1 : 0;
        pos++;
    }
}
int find(char s[],char ss[])
{
    int ret = 0;
    int lens = strlen(s);
    int lenss = strlen(ss);
    get_fail(ss,lenss);
    int root = 0;
    int pos = 0;
    while(pos<lens)
    {
        while(root && s[pos]!=ss[root]) root = fail[root];
        if(s[pos] == ss[root]) root++;
        if(root == lenss) root = 0 , ret++;
        pos++;
    }
    return ret;
}
int main()
{
    freopen("cut.in","r",stdin);
    freopen("cut.out","w",stdout);
    while(scanf("%s%s",s,ss) && s[0]!='#')
    {
        int ans = find(s,ss);
        printf("%d\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值