时间限制:4000ms单点时限:4000ms内存限制:256MB描述
你知道KMP吗?它是用于判断一个字符串是否是另一个字符串的子串的算法。今天我们想去扩展它。
在信息理论中,在两个相同长度的字符串之间的海明码距离是:两个字符串相同位置对应的字符不同的位置数目。换种说法,它表示将一个字符串转化为另一个字符串所需要改变字符的最小数目。
下面这些字符串之间的海明码距离:
"karolin"和"kathrin"是3.
"karolin"和"kerstin"是3.
1011101和1001001是2.
2173896和2233796是3.
现在给定两个字符串stra,strb,和一个整数k。对于stra中的一个子串,如果它的长度和strb的相同且它们之间的海明码距离不超过k,我们认为它们是匹配的。
那么我们想知道在stra中有多少子串是和strb是匹配的。
输入
有多组测试(大约100),每个用例占3行。
第一行是stra。
第二行是strb。
第三行是k。
请处理到文件末尾。
【参数说明】
1<=stra,strb的长度<=100000
stra,strb只包含小写字母
0<=k<=5
输出
对于每个测试用例,以输出结果占一行。
- 样例输入
abcde f 0 abcde f 1 karolin kathrin 3
- 样例输出
0 5 1
AC代码:
1 #include<set>
2 #include<map>
3 #include<cmath>
4 #include<queue>
5 #include<cstdio>
6 #include<vector>
7 #include<string>
8 #include<cstdlib>
9 #include<cstring>
10 #include<iostream>
11 #include<algorithm>
12 using namespace std;
13
14 #define mem(a, b) (memset(a, b, sizeof(a)))
15 #define pb push_back
16 #define all(v) v.begin(), v.end()
17 #define rall(v) v.rbegin(), v.rend()
18 #define rep(i, m) for (int i = 0; i < (int)(m); i++)
19 #define rep2(i, n, m) for (int i = n; i < (int)(m); i++)
20 typedef unsigned long long ULL;
21 typedef pair<int, int> pii;
22
23 const int oo = (int) 1e9;
24 const double PI = 2 * acos(0);
25 const double eps = 1e-9;
26
27 const int P = 131;
28 const int MAX_N = 100010;
29 ULL ha[MAX_N], hb[MAX_N];
30 ULL p[MAX_N];
31
32 ULL get(ULL h[], int l, int r) {
33 return h[r] - h[l] * p[r - l];
34 }
35
36 char sa[MAX_N], sb[MAX_N];
37 int main(void) {
38 p[0] = 1;
39 for (int i = 1; i < MAX_N; ++i)
40 p[i] = p[i - 1] * P;
41
42 while (~scanf("%s", sa + 1)) {
43 scanf("%s", sb + 1);
44 int k;
45 scanf("%d", &k);
46
47 int lenA = strlen(sa + 1);
48 int lenB = strlen(sb + 1);
49 for (int i = 1; i <= lenA; ++i) {
50 ha[i] = ha[i - 1] * P + sa[i];
51 }
52 for (int i = 1; i <= lenB; ++i) {
53 hb[i] = hb[i - 1] * P + sb[i];
54 }
55
56 int ans = 0;
57 for (int i = lenB; i <= lenA; ++i) {
58 int cnt = 0;
59
60 int za = i, zb = lenB;
61 while ( 1 ) {
62 int l = 0, r = zb + 1;
63 while (r - l > 1) {
64 int mid = (l + r) >> 1;
65 if (get(ha, za - mid, za) == get(hb, zb-mid, zb)) {
66 l = mid;
67 } else {
68 r = mid;
69 }
70 }
71 //printf("l: %d
", l);
72 if (l == zb) break;
73 za -= l + 1;
74 zb -= l + 1;
75 ++cnt;
76 if (cnt > k) break;
77 if (zb <= 0) break;
78 }
79
80 if (cnt <= k) ++ans;
81 }
82 printf("%d
", ans);
83 }
84
85 return 0;
86 }