穿
时间限制: 1 Sec 内存限制: 128 MB
题目描述
乌龟得到了他的基因组,一个只包含“ATCG”四种字母的字符串。乌龟想起科学家说,基因组中很多片段都多次重复出现,而且这种重复是很有意义的,于是他想计算一下自己基因组里片段的重复情况。
给定一个基因组,其中一个长度为k的子串称为一个“k-片段”。乌龟希望你计算出基因组中不同的k-片段数量。例如,基因组“TACAC”的2-片段有“TA” ,“AC”,“CA”,“AC”,其中不同的片段数量有3个。
输入
三个整数n,k,R1,表示基因组的长度,片段的长度和数列生成的首项。基因组第i(1 in)个字符在Ri mod 4的值为0,1,2,3时分别为A, T,C,G
试题中使用的生成数列R定义如下:整数0≤R1<201701在输入中给出。对于i> 1,Ri =(Ri-1×6807 + 2831)mod 201701。
输出
一个整数,表示不同的k-片段的数量
样例输入
复制样例数据
20 2 37
样例输出
10
提示
数据规模
30%的数据满足n≤10;
100%的数据满足1≤n≤105,1≤k≤10
直接用c++中的string类,快速解决。。
/**/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <stack>
#include <queue>
typedef long long LL;
using namespace std;
int n, k, r;
char s[] = "ATCG";
char str[100005];
int main()
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
scanf("%d %d %d", &n, &k, &r);
if(k > n) {printf("0\n"); return 0;}
str[1] = s[r % 4];
for (int i = 2; i <= n; i++){
str[i] = s[(r * 6807 % 201701 + 2831) % 201701 % 4];
r = (r * 6807 % 201701 + 2831) % 201701;
}
string s1;
map<string, int>mp;
int ans = 0, cnt = 1;
while(cnt <= k) s1 = str[cnt++] + s1;
mp[s1] = 1, ans++;
for (int i = k + 1; i <= n; i++){
s1.pop_back();
s1 = str[i] + s1;
if(!mp[s1]) ans++, mp[s1] = 1;
}
printf("%d\n", ans);
return 0;
}
/**/