思路:
存的时候直接存相邻元素的差,然后直接KMP就行了。不管起始位置的高度是多少,下一个元素与它的差是固定的。
代码:
#include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> #include<vector> using namespace std; #define MAXN 200005 int n,m,a[MAXN],b[MAXN]; int T[MAXN],P[MAXN],f[MAXN]; void getFail() { int len=m; f[0]=f[1]=0; for(int i=1;i<len;i++) { //如果i点匹配失败,寻找对应的匹配点 int j=f[i]; //如果j点在上一个匹配点依然失败,则继续向上寻找当前点的匹配点,直到匹配或达到起始点。 while(j && P[j]!=P[i]) j=f[j]; //更新下一个失配点,如果本失配点找到了匹配点,则下一个失配值需要更新到匹配点+1;如果没有找到匹配点,则更新到起点。 f[i+1] = P[j]==P[i]? j+1:0; } } int find() { int j=0,cnt=0; for(int i=0;i<n;i++) { //如果T[i]匹配失败,则向上寻找前面的匹配点 while(j && P[j]!=T[i]) j=f[j]; //如果找到了一个匹配点,则将j后移一位(即继续匹配下一位) if(P[j]==T[i]) j++; if(j==m) cnt++,j=f[j]; } return cnt; } int main() { scanf("%d%d",&n,&m); for(int i=0;i<n;i++) scanf("%d",&a[i]); for(int i=0;i<m;i++) scanf("%d",&b[i]); if(m==1) { printf("%d\n",n); exit(0); } else if(n==1) { printf("0\n"); exit(0); } else { for(int i=0;i<n-1;i++) T[i]=a[i+1]-a[i]; for(int i=0;i<m-1;i++) P[i]=b[i+1]-b[i]; n--; m--; getFail(); printf("%d\n",find()); } return 0; }