题意:给一组数列A,再给一个匹配数列B,问将A里最多有多少不重叠的大小关系和B一样的数列。
思路:典型的kmp,只需要把A和B的关系搞出来匹配就可以了。
直接copy了之前写的code改了下。
#include<cstdio>
#include <cstring>
const int M = 1e5 + 20;
int n, m, a[M], b[M], aa[M], bb[M], next[M];
void getnext()
{
int i = 0, j = -1;
next[0] = -1;
while(i < m)
{
if(j == -1 || b[j] == b[i])
{
j++;i++;
next[i] = j;
}
else
j = next[j];
}
}
int kmp(int st)
{
int i = st, j = 0;
while(i < n)
{
if(a[i] == b[j] || j == -1)
j++, i++;
else
j = next[j];
if(j == m)
return i - m + 1;
}
return -1;
}
main()
{
int t;
while(~scanf("%d %d %d", &n, &m, &t)){
memset(next, 0, sizeof next);
for(int i = 0; i < n; i++)
scanf("%d", &aa[i]);
for(int i = 1; i < n; i++)
a[i - 1] = aa[i] > aa[i - 1] ? 2 : aa[i] == aa[i - 1] ? 1 : 0;
for(int i = 0; i < m; i++)
scanf("%d", &bb[i]);
for(int i = 1; i < m; i++)
b[i - 1] = bb[i] > bb[i - 1] ? 2 : bb[i] == bb[i - 1] ? 1 : 0;
if(m == 1){
printf("%d\n", n);
continue;
}
n--, m--;
int ans = 0, st = 0;
getnext();
while(true){
int p = kmp(st);
if(p == -1) break;
else {
ans++;
st = p + m;
}
}
printf("%d\n", ans);
}
}