ZZULIOJ-2264——sequence

谁践踏了优雅 2022-04-12 13:48 218阅读 0赞

sequence

题目描述

给定一个含n个数的序列A和一个含m (m<=n) 个数的序列B。

询问在A中有多少段连续的长为m的子序列Ak,Ak+1,…,Ak+m-1使得对于任意1<=i, j<=m满足Ak+i-1-Bi=Ak+j-1-Bj

输入

第一行两个整数n,m (1 <= m <= n <= 10^6)

接下来一行n个整数,描述序列A (Ai <= 10^9)

接下来一行m个整数,描述序列B (Bi <= 10^9)

输出

输出一个数表示答案

样例输入

7 4
6 6 8 5 5 7 4
7 7 9 6

样例输出

2

题意描述:

判断一个主串中有多少段满足与子串的关系,A(k+i-1)-Bi=A(k+j-1)-Bj。

解题思路:

主串匹配模式串,KMP模板,关系式可进行转化A(k+i-1)-A(k+j-1)=Bi-Bj。将主串和模式串douj都进行处理得到相邻两个的差值,进行匹配。

程序代码:

  1. #include<stdio.h>
  2. int next[1000010];
  3. int s1[1000010],s2[1000010];
  4. int a[1000010],b[1000010];
  5. void get_next(int s[],int len)
  6. {
  7. int i,j;
  8. i=1;j=0;
  9. next[0]=0;
  10. while(i<len)
  11. {
  12. if(s[i]==s[j])
  13. {
  14. next[i]=j+1;
  15. i++;
  16. j++;
  17. }
  18. if(j==0&&s[i]!=s[j])
  19. {
  20. next[i]=0;
  21. i++;
  22. }
  23. if(j>0&&s[i]!=s[j])
  24. j=next[j-1];
  25. }
  26. }
  27. int kmp(int s1[],int len1,int s2[],int len2)
  28. {
  29. int n,i,j;
  30. i=0;j=0;
  31. n=0;
  32. while(i<len1)
  33. {
  34. if(s1[i]==s2[j])
  35. {
  36. j++;
  37. if(j==len2)
  38. {
  39. n++;
  40. j=next[j-1];
  41. }
  42. i++;
  43. }
  44. if(j==0&&s1[i]!=s2[j])
  45. i++;
  46. if(j!=0&&s1[i]!=s2[j])
  47. j=next[j-1];
  48. }
  49. return n;
  50. }
  51. int main()
  52. {
  53. int n,m,num,i,j,u;
  54. while(scanf("%d%d",&n,&m)!=EOF)
  55. {
  56. for(i=0;i<n;i++)
  57. scanf("%d",&a[i]);
  58. for(i=0;i<n-1;i++)
  59. s1[i]=a[i+1]-a[i];
  60. for(i=0;i<m;i++)
  61. scanf("%d",&b[i]);
  62. for(i=0;i<m-1;i++)
  63. s2[i]=b[i+1]-b[i];
  64. get_next(s2,m-1);
  65. num=kmp(s1,n-1,s2,m-1);
  66. printf("%d\n",num);
  67. }
  68. return 0;
  69. }

发表评论

表情:
评论列表 (有 0 条评论,218人围观)

还没有评论,来说两句吧...

相关阅读

    相关 ZZULIOJ-2258——name

                                                      name 题目描述 lpq同学最近突然对外国人的名字产生了兴趣,