2017计蒜之道初赛第一场B

题目链接:https://nanti.jisuanke.com/t/15500

阿里“天池”竞赛平台近日推出了一个新的挑战任务:对于给定的一串 DNA 碱基序列 tt,判断它在另一个根据规则生成的 DNA 碱基序列 ss 中出现了多少次。

首先,定义一个序列 ww

\displaystyle w_{i} = \begin{cases}b, & i = 0\\(w_{i-1} + a) \mod n, & i > 0\end{cases}wi={b,(wi1+a)modn,i=0i>0

接下来,定义长度为 nn 的 DNA 碱基序列 ss(下标从 00 开始):

\displaystyle s_{i} = \begin{cases}A , & (L \le w_{i} \le R) \land (w_{i}\ \mathrm{mod}\ 2 = 0)\\T , & (L \le w_{i} \le R) \land (w_{i}\ \mathrm{mod}\ 2 = 1)\\G , & ((w_{i} < L) \lor (w_{i} > R)) \land (w_{i}\ \mathrm{mod}\ 2 = 0)\\C , & ((w_{i} < L) \lor (w_{i} > R)) \land (w_{i}\ \mathrm{mod}\ 2 = 1)\end{cases}si=A,T,G,C,(LwiR)(wi mod 2=0)(LwiR)(wi mod 2=1)((wi<L)(wi>R))(wi mod 2=0)((wi<L)(wi>R))(wi mod 2=1)

其中 \land 表示“且”关系,\lor 表示“或”关系,a\ \mathrm{mod}\ ba mod b 表示 aa 除以 bb 的余数。

现给定另一个 DNA 碱基序列 tt,以及生成 ss 的参数 n , a , b , L , Rn,a,b,L,R,求 tt 在 ss 中出现了多少次。

输入格式

数据第一行为 55 个整数,分别代表 n , a , b , L , Rn,a,b,L,R。第二行为一个仅包含ATGC的一个序列 tt

数据保证 0 < a < n,0<a<n, 0 \le b < n,0b<n, 0 \le L \le R < n,0LR<n, |t| \le 10^{6}t106a,na,n 互质。

对于简单版本,1 \leq n \leq 10^{6}1n106

对于中等版本,1 \leq n \leq 10^{9}, a = 11n109,a=1

对于困难版本,1 \leq n \leq 10^{9}1n109

输出格式

输出一个整数,为 tt 在 ss 中出现的次数。

样例说明

对于第一组样例,生成的 ss 为TTTCGGAAAGGCC

样例输入1

13 2 5 4 9
AGG

样例输出1

1

样例输入2

103 51 0 40 60
ACTG

样例输出2

5

kmp就是关于字符串匹配的算法;
题意:头一次见这种题型,总共有四道题,后三道是一样的,只是数据范围不同;这里是第二道题,暴力kmp就可;
思路:按照题意生成字符串s,然后匹配s与t;因为本题对于样例 sss ss 输出的是2,我的模板不能过计算重叠的(我是了解会套模板,不会修改),这里使用的是kuangbin的模板;
代码:
#include
#include
#include
using namespace std;
const int maxn=1000006;

char s[maxn],t[maxn];
int w[maxn];
int nextt[maxn];
int m,n;
int N,a,b,l,r;


void kmp_pre(char x[],int m,int nextt[])
{
    int i,j;
    j=nextt[0]=-1;
    i=0;
    while(i=m)
        {
            ans++;
            j=nextt[j];
        }
    }
    return ans;
}

int main()
{
    scanf("%d%d%d%d%d",&N,&a,&b,&l,&r);
    w[0]=b;
    for(int i=1;i=l&&w[i]<=r)&&w[i]%2==0)
            s[i]='A';
        else if((w[i]>=l&&w[i]<=r)&&w[i]%2==1)
            s[i]='T';
        else if((w[i]r)&&w[i]%2==0)
            s[i]='G';
        else if((w[i]r)&&w[i]%2==1)
            s[i]='C';
    }

    scanf("%s",&t);
    n=strlen(s),m=strlen(t);
    int ans=kmp_count(t,m,s,n);
    printf("%d\n",ans);
    return 0;
}


你可能感兴趣的:(KMP)