hdu 1711(KMP的簡單應用)
阿新 • • 發佈:2019-02-02
題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=1711
Number Sequence
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 11475 Accepted Submission(s): 5234
Problem 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
Source
思路:KMP的第一種寫法:
KMP的第二種寫法:#include <iostream> #include <stdio.h> #include <string.h> #include <string> const int N=1000100; using namespace std; int a[N],b[N],next[N]; int n,m; void get_next() { int i=1,j=0; next[1]=0; while(i<m) { if(j==0||b[i]==b[j]) { ++i; ++j; next[i]=j; } else j=next[j]; } } int kmp() { int i=1,j=1; while(i<=n&&j<=m) { if(j==0||a[i]==b[j]) { ++i; ++j; } else j=next[j]; } if(j>m)return i-m; return -1; } int main() { int T; cin>>T; while(T--) { scanf("%d%d",&n,&m); memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); memset(next,0,sizeof(next)); for(int i=1;i<=n;i++)scanf("%d",&a[i]); for(int i=1;i<=m;i++)scanf("%d",&b[i]); get_next(); printf("%d\n",kmp()); } return 0; }
#include <cstdlib> #include <iostream> #include <stdio.h> #include <string> #include <string.h> using namespace std; #define N 1000000+10 int len,len1,next[N]; int str[N],str1[N]; void get_next() { int i=0,j=-1; next[0]=-1; while(i<=len1) { if(j==-1||str1[i]==str1[j]) { i++;j++; next[i]=j; } else j=next[j]; } } int kmp() { int i=0,j=0; while(i<len&&j<len1) { if(j==-1||str[i]==str1[j]) { i++;j++; } else j=next[j]; } if(j>=len1) return i-len1+1; return 0; } int main(int argc, char *argv[]) { int kk; scanf("%d",&kk); while(kk--){ memset(str,0,sizeof(str)); memset(str1,0,sizeof(str1)); memset(next ,0,sizeof(next)); scanf("%d%d",&len,&len1); for(int i=0;i<len;++i) scanf("%d",&str[i]); for(int i=0;i<len1;++i) scanf("%d",&str1[i]); get_next(); int flag=kmp(); if(flag==0) printf("-1\n"); else printf("%d\n",flag); } return 0; }