计蒜客-阿里天池的新任务(kmp求字符串出现的次数)

题目链接:2017计蒜客第一场

题目大意:

     根据题目中给出的碱基序列的生成规则,求一个现有碱基序列在新得碱基序列中出现的次数

题目思路:

     n比较大,暴力不可行,因此想到了kmp的方法,kmp复杂度O(n+m)


#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
#define maxn 6000005
char s1[maxn],s2[maxn];
ll p[maxn],q[maxn],ans;
void print()  
{  
    int i,j=0;  
    p[1]=0;  
    int len=strlen(s1+1);  
    for(i=2;i<=len;i++)  
    {  
        while(j>0 && s1[j+1]!=s1[i])  
             j=p[j];  
        if(s1[i]==s1[j+1])  
          j++;  
        p[i]=j;  
    }   
}  
void kmp()  
{  
    int i,j=0,sum=strlen(s1+1);  
    int len=strlen(s2+1);  
    for(i=1;i<=len;i++)  
    {  
        while(j>0 && s2[i]!=s1[j+1])  
         j=p[j];  
        if(s1[j+1]==s2[i])  
         j++;  
        if(j==sum)  
        {  
             j=p[j];
	     ans++;
         }   
    }  
}    
int main(void)
{
	ll n,a,b,l,r,i,j;
	scanf("%lld%lld%lld%lld%lld",&n,&a,&b,&l,&r);
	scanf("%s",s1+1);
	for(i=0;i<n;i++)
	{
		if(i==0)
			q[i]=b;
		else
		q[i]=(q[i-1]+a)%n;
		if(q[i]>=l && q[i]<=r && q[i]%2==0)
			s2[i+1]='A';
		else if(q[i]>=l && q[i]<=r && q[i]%2==1)
			s2[i+1]='T';
		else if((q[i]<l || q[i]>r) && q[i]%2==0)
			s2[i+1]='G';
		else if((q[i]<l || q[i]>r) && q[i]%2==1)
			s2[i+1]='C';
	}
	print();
	kmp();
	printf("%lld\n",ans);
	return 0;
}

    原文作者:KMP算法
    原文地址: https://blog.csdn.net/haut_ykc/article/details/72597750
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞