HDU 2087 (KMP)

剪花布条

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 14553    Accepted Submission(s): 9213

Problem Description

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

Input

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

Output

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

Sample Input

abcde a3
aaaaaa  aa
#

Sample Output

0
3

题意:最多能从文本串中剪出多少个模式串。

因为不能重叠,所以当j匹配的模式串的末尾并且匹配成功时直接把j变成0从新匹配就

好了。

#include <cstring>
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
#define maxn 1111

char P[maxn], T[maxn];
int n, m;
#define next Next
int next[maxn];

void get_next (char *p) {
    int t;
    t = next[0] = -1;
    int j = 0;
    while (j+1 < m) {
        if (t < 0 || p[j] == p[t]) {//匹配
            j++, t++;
            next[j] = t;
        }
        else //失配
            t = next[t];
    }
}  

int kmp () {
	int ans = 0;
	get_next (P);
	int i = 0, j = 0;
	while (i < n && j < m) {
		if (j < 0 || T[i] == P[j]) {
			if (j == m-1) {
				ans++;
				i++;
				j = 0;
				continue;
			}
			i++, j++;
		}
		else {
			j = next[j];
		}
	}
	return ans;
}

int main () {
	while (cin >> T) {
		if (T[0] == '#' && strlen (T) == 1)
			break;
		cin >> P;
		n = strlen (T);
		m = strlen (P);
		printf ("%d\n", kmp ());
	}
	return 0;
}
时间: 2024-08-20 15:47:39

HDU 2087 (KMP)的相关文章

HDU 2087 (KMP不可重叠的匹配) 花布条

题意: 用两个字符串分别表示布条和图案,问能从该布条上剪出多少这样的图案. 分析: 毫无疑问这也是用KMP匹配,关键是一次匹配完成后,模式串应该向后滑动多少. 和上一题 HDU 1686 不同,两个图案肯定不能在母串中有交叉的部分,所以当匹配成功一次后,应当滑动整个模式串的长度. 和上一题比,代码几乎不变,只是 j = next[j]; 变为 j = 0; 1 #include <cstdio> 2 #include <cstring> 3 4 const int maxn = 1

HDU 2087 kmp模板题

s为主串 t为模板串 求t的nextt 加const #include<stdio.h> #include<string.h> #include<algorithm> #include<map> #include<math.h> #include<queue> using namespace std; char s[1005]; char t[1005]; int nextt[1005]; void makenext(const ch

HDU 2087 剪花布条 KMP题解

KMP的应用,不过查找的时候注意一点就够了:查找到一个子串的时候,直接跳过整个串,而不是使用next数组前跳,因为根据题意需要剪出小饰条,小饰条之间不能重叠. const int MAX_N = 1001; char txt[MAX_N], pat[MAX_N]; int next[MAX_N], len; void genNext() { for (int i = 1, j = 0; i < len; ) { if (pat[i] == pat[j]) next[i++] = ++j; els

hdu 1711 KMP模板题

// hdu 1711 KMP模板题 // 贴个KMP模板吧~~~ #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std; const int MAX_N = 1000008; const int MAX_M = 10008; int T[MAX_N]; int p[MAX_M]; int f[MAX_M]; int

hdu 1686 KMP模板

1 // hdu 1686 KMP模板 2 3 // 没啥好说的,KMP裸题,这里是MP模板 4 5 #include <cstdio> 6 #include <iostream> 7 #include <cstring> 8 #include <algorithm> 9 10 using namespace std; 11 12 const int MAX_N = 1000008; 13 const int MAX_M = 10008; 14 char T

Cyclic Nacklace HDU 3746 KMP 循环节

Cyclic Nacklace HDU 3746 KMP 循环节 题意 给你一个字符串,然后在字符串的末尾添加最少的字符,使这个字符串经过首尾链接后是一个由循环节构成的环. 解题思路 next[len]-len的差即是循环部分的长度. 这个是重点.这个题目自己开始没有想明白,看的博客,推荐这个. 代码实现 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const i

(KMP)剪花布条 -- hdu -- 2087

http://acm.hdu.edu.cn/showproblem.php?pid=2087 剪花布条 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 11793    Accepted Submission(s): 7574 Problem Description 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案.对

hdu 2087(KMP的简单运用)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2087 剪花布条 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 8742    Accepted Submission(s): 5722 Problem Description 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一

题解报告:hdu 2087 剪花布条(KMP入门)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2087 Problem Description 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案.对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢? Input 输入中含有一些数据,分别是成对出现的花布条和小饰条,其布条都是用可见ASCII字符表示的,可见的ASCII字符有多少个,布条的花纹也有多少种花样.花纹条和小饰条不会超过1000个字符长.如果遇见#字符