标签:
题目链接:http://acm.uestc.edu.cn/#/problem/show/1091
题目大意:求模式串p,在s中出现的次数,但是p能平移到s即可,比如s: 1 3 4和 p :0 2 3;
题目思路:处理出每一位相对前一位的变化,然后KMP即可;
代码:
//author:ACsorry //result:Yes #include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<vector> #include<set> #include<map> using namespace std; typedef long long ll; typedef unsigned long long ull; const int N=2000007; int a[N],b[N]; int s[N],p[N]; int nxt[N]; int ans; void getNext(int m) { nxt[0]=-1; for(int i=1,j=-1;i<m-1;i++){ while(j>=0&&p[i]!=p[j+1]) j=nxt[j]; if(p[i]==p[j+1]) j++; nxt[i]=j; } } void KMP(int n,int m) { for(int i=0,j=-1;i<n-1;i++){ while(j>=0&&s[i]!=p[j+1]) j=nxt[j]; if(s[i]==p[j+1]) j++; if(j==m-2) j=nxt[j],ans++; } } int main() { int n,m; scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",a+i); for(int i=0;i<n-1;i++) s[i]=a[i+1]-a[i]; scanf("%d",&m); for(int i=0;i<m;i++) scanf("%d",b+i); for(int i=0;i<m-1;i++) p[i]=b[i+1]-b[i]; ans=0; getNext(m); KMP(n,m); if(ans){ printf("Wow! Life Winner!\n%d\n",ans); } else printf("Oh. That's impossible. I must have had a dream.\n"); return 0; }
标签:
原文地址:http://blog.csdn.net/code_or_code/article/details/45729049