神奇的kmp

来源:互联网 发布:在线视频网站源码 编辑:程序博客网 时间:2024/06/04 18:47
void pre()  公式{      next[0]=-1;      int j=-1;      for(int i=1;i<m;i++)      {          while(j>=0&&pattern[j+1]!=pattern[i])j=next[j];          if(pattern[j+1]==pattern[i])j++;          next[i]=j;      }  }  


还不怎么熟悉kmp,照葫芦画瓢ac了这两个题!!

A - Number Sequence
Time Limit:5000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
Submit
 
Status
Description
Given two sequences of numbers : a[1], a[2], ...... , a[N], and b[1], b[2], ...... , b[M] (1 <= M <= 10000, 1 <= N <= 1000000). Your task is to find a number K which make a[K] = b[1], a[K + 1] = b[2], ...... , a[K + M - 1] = b[M]. If there are more than one K exist, output the smallest one. 
 
Input
The first line of input is a number T which indicate the number of cases. Each case contains three lines. The first line is two numbers N and M (1 <= M <= 10000, 1 <= N <= 1000000). The second line contains N integers which indicate a[1], a[2], ...... , a[N]. The third line contains M integers which indicate b[1], b[2], ...... , b[M]. All integers are in the range of [-1000000, 1000000]. 
 
Output
For each test case, you should output one line which only contain K described above. If no such K exists, output -1 instead. 
 
Sample Input
 2
13 5
1 2 1 2 3 1 2 3 1 3 2 1 2
1 2 3 1 3
13 5
1 2 1 2 3 1 2 3 1 3 2 1 2
1 2 3 2 1 
 
Sample Output
 6

-1 

#include<string.h>#include<stdio.h>int a[100000],b[1000000];int pattern[11111];int next[11111];void pre(int len){int i = 0, j = -1;next[0] = -1;while(i != len){if(j == -1 || pattern[i] == pattern[j])next[++i] = ++j;elsej = next[j];}}int main(){    int n,m,k;    int j,i;    int a[100],b[100];    scanf("%d",k);    while(k--)    {        scanf("%d%d",&n,&m);        for(i=0;i<n;i++) scanf("%d",&a[i]);        for(i=0;i<m;i++) scanf("%d",&b[i]);        pre(m);         j=0;         int c=  0;    for(i=0;i<n;i++){    while(j&&a[i] !=  b[j])j = next[j];    if(a[i] == b[j])j++;    if(j == m){c = 1;break;}    }    if(c) printf("%d\n",i-m+2);    else printf("-1\n");}}


C - 剪花布条
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
Submit
 
Status
Description
一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图案。对于给定的花布条和小饰条,计算一下能从花布条中尽可能剪出几块小饰条来呢? 
 
Input
输入中含有一些数据,分别是成对出现的花布条和小饰条,其布条都是用可见ASCII字符表示的,可见的ASCII字符有多少个,布条的花纹也有多少种花样。花纹条和小饰条不会超过1000个字符长。如果遇见#字符,则不再进行工作。 
 
Output
输出能从花纹布中剪出的最多小饰条个数,如果一块都没有,那就老老实实输出0,每个结果之间应换行。 
 
Sample Input
 abcde a3
aaaaaa  aa
#
        
 
Sample Output
 0

 

#include<string.h>#include<stdio.h>char  a[100000],b[1000000];int pattern[11111];int next[11111];void pre(int len){int i = 0, j = -1;next[0] = -1;while(i != len){if(j == -1 || pattern[i] == pattern[j])next[++i] = ++j;elsej = next[j];}}int main(){    while(scanf("%s",a)!=EOF)    {        if(strcmp(a,"#")==0) break;        scanf("%s",b);    int len1=strlen(a);    int  len2=strlen(b);        pre(len2);        int i,j=0;         int c=0;    for(i=0;i<len1;i++){    while(j&&a[i] !=  b[j])j = next[j];    if(a[i] == b[j])j++;    if(j == len2){j=0;c++;}    }    printf("%d\n",c);    }}


0 0
原创粉丝点击