HDU1711 Number Sequence
题目链接
题意:给定数组 $a_i(1\le i\le n)$ 和 $b_i(1\le i\le m)$,求最小的 $k$ 满足 $a_k=b_1,\cdots,a_{k+m-1}=b_m$。
KMP 模板题。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
#include <bits/stdc++.h>
using namespace std;
#define debug(x) cout << #x << " is " << x << endl
typedef long long ll;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f, N = 1e6 + 5, M = 1e4 + 5;
int t, n, m;
int a[N], b[M];
int nxt[M];
void getnext() {
nxt[0] = -1;
int j = -1;
for (int i = 1; i < m; ++i) {
while (j != -1 && b[i] != b[j+1]) j = nxt[j];
if (b[i] == b[j+1]) j++;
nxt[i] = j;
}
}
int kmp() {
int j = -1;
for (int i = 0; i < n; ++i) {
while (j != -1 && a[i] != b[j+1]) j = nxt[j];
if (a[i] == b[j+1]) j++;
if (j == m - 1) return i - m + 2;
}
return -1;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> t;
while (t--) {
cin >> n >> m;
for (int i = 0; i < n; ++i) cin >> a[i];
for (int i = 0; i < m; ++i) cin >> b[i];
getnext();
cout << kmp() << '\n';
// for (int i = 0; i < m; ++i) cout << nxt[i] << " \n"[i == m - 1];
}
return 0;
}
|
HDU1686 Oulipo
题目链接
题意:给出单词 $W(1\le|W|\le1e4)$ 和文本 $T(|W|\le|T|\le1e6)$,求 $W$ 在 $T$ 中出现次数。
KMP 模板题。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
#include <bits/stdc++.h>
using namespace std;
#define debug(x) cout << #x << " is " << x << endl
typedef long long ll;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f, M = 1e4 + 5;
int t, n, m;
string W, T;
int nxt[M];
void getnext() {
nxt[0] = -1;
int j = -1;
for (int i = 1; i < m; ++i) {
while (j != -1 && W[i] != W[j+1]) j = nxt[j];
if (W[i] == W[j+1]) j++;
nxt[i] = j;
}
}
int kmp() {
int res = 0, j = -1;
for (int i = 0; i < n; ++i) {
while (j != -1 && T[i] != W[j+1]) j = nxt[j];
if (T[i] == W[j+1]) j++;
if (j == m - 1) res++, j = nxt[j];
}
return res;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> t;
while (t--) {
cin >> W >> T;
n = T.length(), m = W.length();
getnext();
cout << kmp() << '\n';
}
return 0;
}
|
HDU2087 剪花布条
题目链接
题意:求子串不重叠出现次数。
和上题一样,改一点就行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
#include <bits/stdc++.h>
using namespace std;
#define debug(x) cout << #x << " is " << x << endl
typedef long long ll;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f, M = 1e3 + 5;
int n, m;
string a, b;
int nxt[M];
void getnext() {
nxt[0] = -1;
int j = -1;
for (int i = 1; i < m; ++i) {
while (j != -1 && b[i] != b[j+1]) j = nxt[j];
if (b[i] == b[j+1]) j++;
nxt[i] = j;
}
}
int kmp() {
int res = 0, j = -1;
for (int i = 0; i < n; ++i) {
while (j != -1 && a[i] != b[j+1]) j = nxt[j];
if (a[i] == b[j+1]) j++;
if (j == m - 1) res++, j = -1;
}
return res;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
while (cin >> a && a[0] != '#') {
cin >> b;
n = a.length(), m = b.length();
getnext();
cout << kmp() << '\n';
}
return 0;
}
|
POJ2752 Seek the Name, Seek the Fame
题目链接
题意:求字符串既是前缀又是后缀的子串长度。
拓展 KMP。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define debug(x) cout << #x << " is " << x << endl
typedef long long ll;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f, N = 4e5 + 5;
int n;
string s;
int z[N];
void getz() {
memset(z, 0, sizeof(z));
int l = 0, r = 0;
for (int i = 1; i < n; ++i) {
if (i <= r) z[i] = min(r - i + 1, z[i-l]);
while (i + z[i] < n && s[i+z[i]] == s[z[i]]) z[i]++;
if (i + z[i] - 1 > r) l = i, r = i + z[i] - 1;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
while (cin >> s) {
n = s.length();
getz();
for (int i = n - 1; i > 0; --i) {
if (i + z[i] == n) cout << z[i] << ' ';
}
cout << n << '\n';
}
return 0;
}
|
HDU3068 最长回文
题目链接
题意:多组输入,求字符串所包含的最长回文长度。
manacher 裸模板题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
#define debug(x) cout << #x << " is " << x << endl
typedef pair<int, int> pii;
typedef long long ll;
const int INF = 0x3f3f3f3f, N = 3e5 + 5;
int n, p[N], ans;
char s[N], str[N];
void init() {
str[0] = str[1] = '#';
for (int i = 0; i < n; ++i) {
str[(i<<1)+2] = s[i];
str[(i<<1)+3] = '#';
}
n = (n<<1) + 2; str[n] = 0;
}
void manacher() {
int maxr = 0, id = 0;
for (int i = 1; i < n; ++i) {
if (maxr > i) p[i] = min(p[2*id-i], maxr - i);
else p[i] = 1;
while (str[i+p[i]] == str[i-p[i]]) ++p[i];
if (i + p[i] > maxr) { maxr = i + p[i]; id = i; }
ans = max(ans, p[i] - 1);
}
}
int main()
{
while (~scanf("%s", s)) {
n = strlen(s);
ans = 0;
init();
manacher();
printf("%d\n", ans);
}
return 0;
}
|