• hdu 5918(强行水过去..正解KMP)


    Sequence I

    Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 216    Accepted Submission(s): 93


    Problem Description
    Mr. Frog has two sequences a1,a2,,an and b1,b2,,bm and a number p. He wants to know the number of positions q such that sequence b1,b2,,bm is exactly the sequence aq,aq+p,aq+2p,,aq+(m1)p where q+(m1)pn and q1.
     
    Input
    The first line contains only one integer T100, which indicates the number of test cases.

    Each test case contains three lines.

    The first line contains three space-separated integers 1n106,1m106 and 1p106.

    The second line contains n integers a1,a2,,an(1ai109).

    the third line contains m integers b1,b2,,bm(1bi109).
     
    Output
    For each test case, output one line “Case #x: y”, where x is the case number (starting from 1) and y is the number of valid q’s.
     
    Sample Input
    2 6 3 1 1 2 3 1 2 3 1 2 3 6 3 2 1 3 2 2 3 1 1 2 3
     
    Sample Output
    Case #1: 2 Case #2: 1
     
    Source
     
    题意:给定数组 a1...an ,b1...bm, 以及间隔 d,问 a 中使得存在 aq ,aq+d , aq+2d...aq+(m-1)d  和 b数组相等的 q 有多少个?
    题解:标准解法是 KMP,我这双重循环强行水了过去..
    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1000005;
    int a[N],b[N];
    int main()
    {
        int tcase,t=1;
        scanf("%d",&tcase);
        while(tcase--){
            int n,m,k;
            scanf("%d%d%d",&n,&m,&k);
            for(int i=1;i<=n;i++){
                scanf("%d",&a[i]);
            }
            for(int i=1;i<=m;i++){
                scanf("%d",&b[i]);
            }
            if(m>n) {
                printf("Case #%d: %d
    ",t++,0);
                continue;
            }
            int ans = 0;
            for(int i=1;i<=n;i++){
                if(a[i]!=b[1]) continue;
                int idx = 1;
                for(int j=i;j<=n;j+=k){
                    if(a[j]==b[idx]){
                        idx++;
                    }
                    else break;
                    if(idx==m+1){
                        ans++;break;
                    }
                }
            }
            printf("Case #%d: %d
    ",t++,ans);
        }
        return 0;
    }
     KMP解法
    #include <iostream>
    #include <cstring>
    #include <stdio.h>
    #include <stdlib.h>
    #include <algorithm>
    using namespace std;
    
    const int N = 1000002;
    int Next[N];
    int A[N],S[N], T[N];
    int slen, tlen;
    
    void getNext()
    {
        int j, k;
        j = 0; k = -1; Next[0] = -1;
        while(j < tlen)
            if(k == -1 || T[j] == T[k])
                Next[++j] = ++k;
            else
                k = Next[k];
    
    }
    /*
    返回模式串在主串S中出现的次数
    */
    int KMP_Count()
    {
        int ans = 0;
        int i, j = 0;
        if(slen == 1 && tlen == 1)
        {
            if(S[0] == T[0])
                return 1;
            else
                return 0;
        }
        for(i = 0; i < slen; i++)
        {
            while(j > 0 && S[i] != T[j])
                j = Next[j];
            if(S[i] == T[j])
                j++;
            if(j == tlen)
            {
                ans++;
                j = Next[j];
            }
        }
        return ans;
    }
    int main()
    {
    
        int tcase,t=1;
        scanf("%d",&tcase);
        while(tcase--)
        {
            int n,k;
            scanf("%d%d%d",&n,&tlen,&k);
    
            memset(T,0,sizeof(T));
            for(int i=0;i<n;i++) scanf("%d",&A[i]);
            for(int i=0;i<tlen;i++) scanf("%d",&T[i]);
            int ans = 0;
            getNext();
            for(int i=0;i<k;i++){ ///枚举起点
                slen = 0;
                for(int j = i;i+(tlen-1)*k<n&&j<n;j+=k){
                    S[slen++] = A[j];
                }
                if(slen<tlen) continue;
                /*for(int j=0;j<slen;j++){
                    printf("%d ",S[j]);
                }*/
                ans+=KMP_Count();
            }
            printf("Case #%d: %d
    ",t++,ans);
        }
        return 0;
    }
  • 相关阅读:
    sqlserver查询表字段
    Lombok
    属性配置
    计时器与启动加载器
    banner
    互斥锁和条件变量
    System V消息队列
    命令行参数的处理函数getopt
    posix 消息队列
    不定参数
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5931400.html
Copyright © 2020-2023  润新知