博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
简单 hash 入门题目
阅读量:5880 次
发布时间:2019-06-19

本文共 2144 字,大约阅读时间需要 7 分钟。

题目描述

NOIP 复赛之前,HSD 桑进行了一项研究,发现人某条染色体上的一段 DNA 序列中连续的 kkk 个碱基组成的碱基序列与做题的 AC 率有关!于是他想研究一下这种关系。

现在给出一段 DNA 序列,请帮他求出这段 DNA 序列中所有连续 kkk 个碱基形成的碱基序列中,出现最多的一种的出现次数。

输入格式

两行,第一行为一段 DNA 序列,保证 DNA 序列合法,即只含有 A, G, C, T 四种碱基;

第二行为一个正整数 kkk,意义与题目描述相同。

输出格式

一行,一个正整数,为题目描述中所求答案。

样例

样例输入 1

AAAAA1

样例输出 1

5

样例解释 1

对于这段 DNA 序列,连续的 111 个碱基组成的碱基序列只有 A,共出现 555 次,所以答案为 555。

样例输入 2

ACTCACTC4

样例输出 2

2

样例解释 2

对于这段 DNA 序列,连续的 444 个碱基组成的碱基序列为:ACTC, CTCA, TCACCACT。其中 ACTC 出现 222 次,其余均出现 111 次,所以出现最多的次数为 222,即为答案。

数据范围与提示

记 DNA 序列长度为 nnn。

本题共 101010 组数据,只有输出与标准输出一致才可以获得该测试点的分数。

下面给出每组数据的范围和满足性质情况:

测试点编号 nnn kkk 其他
111 =105=10 ^5=105​​ =1=1=1 满足性质
2,32,32,3 ≤5×105\le 5 \times 10 ^55×105​​ =1=1=1 -
444 ≤5×105\le 5 \times 10 ^55×105​​ ≤10\le 1010 满足性质
5,6,7,85,6,7,85,6,7,8 ≤106\le 10 ^6106​​ ≤10\le 1010 -
9,109,109,10 =5×106=5 \times 10 ^6=5×106​​ =10=10=10 -

性质:给出的 DNA 碱基序列中每个碱基均相同。

对于所有数据均保证 k≤nk\le nkn

 

思路分析 : hash 拉链即可解决

代码示例:

using namespace std;#define ll unsigned long longconst ll maxn = 5e6+5;const ll mm = 200007;char s[maxn];ll k, len;ll p = 19873;ll hash_[maxn], pp[maxn];void init_hash() {    hash_[0] = 0; pp[0] = 1;    for(ll i = 1; i <= len; i++) {        hash_[i] = hash_[i-1]*p + (s[i]-'a');         pp[i] = pp[i-1]*p;    }  }struct node{    ll x;    ll cnt = 0;    int next; //!!!}arr[maxn];int head[mm+50];ll tot = 1;ll _max(ll a, ll b){    return a>b?a:b;}void solve() {    ll ans = 1;    memset(head, -1, sizeof(head));        for(ll i = k; i <= len; i++){        ll num = hash_[i]-hash_[i-k]*pp[k];        ll num2 = num%mm;        int f = head[num2];        int sign = 0;        while(f != -1) {            if (arr[f].x == num) {                arr[f].cnt++;                ans = _max(ans, arr[f].cnt);                sign = 1;                break;            }            f = arr[f].next;        }        if (sign) continue;        arr[tot].x = num;        arr[tot].cnt = 1;        arr[tot].next = head[num2];        head[num2] = tot++;    }    printf("%lld\n", ans);}int main() {        scanf("%s", s+1);    len = strlen(s+1);    scanf("%llu", &k);    init_hash();    solve();    return 0;}

 

转载于:https://www.cnblogs.com/ccut-ry/p/9648246.html

你可能感兴趣的文章
下半年过了中项,感谢学院,感谢薛老师,后面就跟着学院的各位老师学与考了
查看>>
RAID磁盘冗余阵列
查看>>
支付宝升级延时到账功能
查看>>
ghost后只剩下一个盘的数据寻回方法
查看>>
输入输出练习
查看>>
Git commit message和工作流规范
查看>>
java面试。答案源于网上
查看>>
yii中取得CActiveDataProvider的分页信息
查看>>
我的大学
查看>>
Google翻译接口收费啦
查看>>
Debian+Apache2服务器
查看>>
linux——编译安装nginx出现报错,以及启动nginx服务时80端口被占用怎么解决?...
查看>>
MySQL库和表的操作
查看>>
shell编程:编译器、解释器 变量
查看>>
yum仓库一些简单介绍
查看>>
HashMap----工作原理
查看>>
Aliware(企业级互联网架构ACP)复习整理-EDAS
查看>>
java线程无法正常停止总结
查看>>
我的友情链接
查看>>
CentOS6.4+Apache+Mariadb+PHP搭建WordPress
查看>>