剪花布条 (HDU-2087)

题面

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

输入

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

输出

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

样例输入

1abcde a3
2aaaaaa  aa
3#

样例输出

10
23

提示

思路

KMP模板题,注意匹配成功之后j=0而不是继续接着上一个的。

代码

 1char s[mxn], t[mxn];
 2int nxt[mxn];
 3
 4void getnxt(char* t, int m)
 5{
 6    int i = 0, j = -1; nxt[0] = -1;
 7    while (i < m)
 8    {
 9        if (j == -1 || t[i] == t[j]) {
10            i++, j++;
11            // if (t[i] == t[j])
12            //     nxt[i] = nxt[j]; // next数组优化
13            // else
14                nxt[i] = j;
15        } else
16            j = nxt[j];
17    }
18}
19
20int KMP(char* s, char* t, int n, int m)
21{
22    int i = 0, j = 0, ans = 0;
23    while (i < n)
24    {
25        if (j == -1 || s[i] == t[j]) {
26            i++, j++;
27            if (j >= m) {   // 匹配
28                ans++;
29                j = 0;
30                // return i-j;
31            }
32        } else
33            j = nxt[j];
34    }
35    return ans;
36    // return -1;
37}
38
39int main()
40{
41    while(scanf("%s", s)==1 && strcmp(s, "#"))
42    {
43        scanf("%s", t);
44        int tl = strlen(t), sl = strlen(s);
45        getnxt(t, tl);
46        printf("%d\n", KMP(s, t, sl, tl));
47    }
48    return 0;
49}