社区讨论
求解算法正确性
P3375【模板】KMP参与者 2已保存回复 1
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @locthwmh
- 此快照首次捕获于
- 2023/10/30 19:29 2 年前
- 此快照最后确认于
- 2023/11/05 06:08 2 年前
RT,用Z算法解border数组。方法是对于每个 ,将 赋值为 ,然后从后往前倒推(
bord[i] = max(bord[i], bord[i + 1]))洛谷数据都过了,请问这个算法是否正确?code:
CPP#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
const int N = 1000000;
char a[N + 10], b[N + N + 10];
int z[N + N + 10];
void get_z(const char *str, const int len, int *arr) {
int maxl = 0, maxr = 0;
// [1, maxr - maxl + 1] = [maxl, maxr]
// [i - maxl + 1, maxr - maxl + 1] = [i, maxr]
arr[1] = len;
for (int i = 2; i <= len; ++ i) {
if (i <= maxr) {
arr[i] = std::min(arr[i - maxl + 1], maxr - i + 1);
}
while (i + arr[i] <= len && str[arr[i] + 1] == str[i + arr[i]])
++ arr[i];
if (i + arr[i] - 1 > maxr) {
maxr = i + arr[i] - 1;
maxl = i;
}
}
return;
}
int n, m;
int bord[N + 10];
int main() {
scanf("%s%s", a + 1, b + 1);
n = strlen(a + 1);
m = strlen(b + 1);
get_z(b, m, z);
// for (int i = 1; i <= m; ++ i) {
// printf("z[%d]=%d\n", i, z[i]);
// }
for (int i = m; i >= 2; -- i) {
bord[i + z[i] - 1] = z[i];
}
for (int i = m - 1; i >= 1; -- i) {
bord[i] = std::max(bord[i], bord[i + 1] - 1);
}
b[m + 1] = '#';
for (int i = 1; i <= n; ++ i) {
b[m + 1 + i] = a[i];
}
get_z(b, m + 1 + n, z);
for (int i = 1; i <= n; ++ i) {
if (z[m + 1 + i] == m)
printf("%d\n", i);
}
for (int i = 1; i <= m; ++ i) {
printf("%d ", bord[i]);
}
printf("\n");
return 0;
}
回复
共 1 条回复,欢迎继续交流。
正在加载回复...