zoukankan      html  css  js  c++  java
  • 栗酱的数列(KMP+思维)

    链接:https://ac.nowcoder.com/acm/problem/14694
    来源:牛客网

    题目描述

    栗酱有一个长度为n的数列A,一个长度为m的数列B,现在询问A中有多少个长度为m的连续子序列A',
    满足(a'1+b1)%k = (a'2+b2)%k = …… = (a'm + bm)%k。

    输入描述:

    第一行一个数T,表示有T组数据。
    对于每组数据,
    第一行三个整数,n, m, k。
    第一行输入n个数, a1,a2,…,an, 表示A数列中的数,
    第二行输入m个数, b1,b2,…,bm, 表示B数列中的数。

    输出描述:

    每一组数据输出一行,满足条件的连续子序列数量。

    具体思路:

    一开始是按照互补的方法去匹配的,然后发现余数不一定为0,然后这种方法就咕咕了。

    然后我们观察那个式子就可以发现,可以转换成这种形式。
    (a1+b1)%k==(a2+b2)%k;

    转换成   (a2+b2-a1-b1)%k==0.这样之后,我们就可以直接去匹配了,这个时候等号右边就变成了定值了。

    AC代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 # define inf 0x3f3f3f3f
     4 # define ll long long
     5 const int maxn = 2e5+100;
     6 int a[maxn];
     7 int b[maxn];
     8 int s[maxn],t[maxn];
     9 int n,m,k;
    10 int nex[maxn];
    11 void getnex()
    12 {
    13     nex[0]=-1;
    14     int i=0,j=-1;
    15     while(i<m-1)
    16     {
    17         if(j==-1||t[i]==t[j])
    18         {
    19             i++;
    20             j++;
    21             nex[i]=j;
    22         }
    23         else
    24         {
    25             j=nex[j];
    26         }
    27     }
    28 }
    29 int kmp()
    30 {
    31     int ans=0;
    32     getnex();
    33 //    for(int i=0;i<=m;i++){
    34 //    cout<<nex[i]<<" ";
    35 //    }
    36 //    cout<<endl;
    37     int i=0,j=0;
    38     while(i<n-1&&j<m-1)
    39     {
    40         if(j==-1||(s[i]+t[j])%k==0)
    41         {
    42             i++;
    43             j++;
    44         }
    45         else
    46             j=nex[j];
    47         if(j==m-1)
    48             ans++,j=nex[j];
    49     }
    50     return ans;
    51 }
    52 int main()
    53 {
    54     int T;
    55     scanf("%d",&T);
    56     while(T--)
    57     {
    58         scanf("%d %d %d",&n,&m,&k);
    59         for(int i=0; i<n; i++)
    60         {
    61             scanf("%d",&a[i]);
    62             a[i]%=k;
    63         }
    64         for(int i=0; i<m; i++)
    65         {
    66             scanf("%d",&b[i]);
    67             //      b[i]%=k;
    68            b[i]%=k;
    69         }
    70         for(int i=0; i<n-1; i++)
    71         {
    72             s[i]=(a[i+1]-a[i]+k)%k;
    73         }
    74         for(int i=0; i<m-1; i++)
    75         {
    76             t[i]=(b[i+1]-b[i]+k)%k;
    77         }
    78         printf("%d
    ",kmp());
    79     }
    80     return 0;
    81 }

     

  • 相关阅读:
    [置顶] app后端设计--总目录
    Centos6.5 nginx+nginx-rtmp配置流媒体服务器
    利用nginx搭建RTMP视频点播、直播、HLS服务器
    如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源
    使用pngquant命令近乎无损压缩PNG图片大小减少70%左右
    字符型图片验证码识别完整过程及Python实现
    python PIL Image模块
    app后端设计(12)--图片的处理
    linux 下如何抓取HTTP流量包(httpry)
    EHcache缓存框架详解
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10909901.html
Copyright © 2011-2022 走看看