DNA匹配问题

描述

DNA(脱氧核糖核酸)为人体中存储基因信息的媒介。核苷酸是一种由亚基构成,排列起来聚合物链。DNA聚合物链也称DNA线。
根据化学成份或获取方式,DNA中的核苷酸基因可以分为四种:adenine,guanine, cytosine and
thymine,我们分别以A,G,C和T表示。单个核苷酸通过端到端的化学行为链接成DNA,简单地说,我们可以作用一系列A,T,C和G构成的串代表一个链,如ATTCGAC,但我们应该注意核苷酸组成的串有方向性,所以我们认为ATTCGAC和CAGCTTA代表两种不同的链。

基因通常不会以自由单链的形式存在。在适当条件下单链将成对出现,并绕着对方,形成了著名的双螺旋结构。这种配对出现于As与Ts,Gs与Ts,因为相互吸引,称为氢键。因此称A/T和G/C为互补碱基对。

Molecular生物实验室是进行DNA实验的,其一项重要的工作是配比两个碱基对线,制成DNA双链。我们要求两个单碱基对线的长度必须相同,同时要求两个单链中相同位置的核苷酸基因为互补碱基对。例如ATTCGAC和TAAGCTG是互补,但CAGCTTA和TAAGCTG不是,ATTCGAC和GTAAGCT也不是。

作为生物研究的助手的你,你的老板交给你一个任务:给定n个单链,找出可以配对双链的最大数目(当然,每个单链最多只能使用一次)。如果n很小时,可以很容易用笔算出,但当n很大时,就不行了。现在要求使用编写程序实现。

输入

输入包括多个测试用例,第一行是一个正整数T(T<=20),表示测试用例个数。在每一个测试用例中,第一行是一个正整数n(n<=10000),表示单链的个数。接下来的n行,每行代表一个单链。每一个单链的长度不超过1000

输出

对每一个测试用例,用一行输出一个整数,即可以配成的最大双链的个数。

样例输入

2
3
ATCG
TAGC
TAGG
2
AATT
ATTA

样例输出

1
0

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

char a[10001][1010];

int main()
{
    int n, m, i, j;
    bool use[100010];
    cin>>n;
    while(n--)
    {
        memset(use,true,sizeof use);
        cin>>m;
        int sum = 0;getchar();
        for(i= 0; i < m; i++)
            gets(a[i]);
        for(i = 0; i < m-1; i++)
        {
            for(j = 0; a[i][j]!=‘\0‘; j++)
            {
                if(a[i][j] == ‘T‘)
                    a[i][j] = ‘A‘;
                else if(a[i][j] == ‘A‘)
                    a[i][j] = ‘T‘;
                else if(a[i][j] == ‘C‘)
                    a[i][j] = ‘G‘;
                else if(a[i][j] == ‘G‘)
                    a[i][j] = ‘C‘;
            }
            for(j = i+1; j < m; j++)
            {
                if(strcmp(a[i],a[j])==0 && use[i] && use[j])
                {
                    sum++;
                    use[i] = false;
                    use[j] = false;
                }
            }
        }
        cout<<sum<<endl;
    }
    return 0;
}
时间: 2024-08-13 16:41:39

DNA匹配问题的相关文章

BZOJ-1264 :[AHOI2006]基因匹配Match(树状数组+DP)

1264: [AHOI2006]基因匹配Match Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 904  Solved: 578[Submit][Status][Discuss] Description 基因匹配(match) 卡卡昨天晚上做梦梦见他和可可来到了另外一个星球,这个星球上生物的DNA序列由无数种碱基排列而成(地球上只有4种),而更奇怪的是,组成DNA序列的每一种碱基在该序列中正好出现5次!这样如果一个DNA序列有N种不同的碱基构成

BZOJ 1264: [AHOI2006]基因匹配Match( LCS )

序列最大长度2w * 5 = 10w, O(n²)的LCS会T.. LCS 只有当a[i] == b[j]时, 才能更新答案, 我们可以记录n个数在第一个序列中出现的5个位置, 然后从左往右扫第二个序列时将第一个序列对应位置的值更新, 用树状数组维护. 时间复杂度O(nlogn) ------------------------------------------------------------------------------------------------- #include<bi

bzoj1264 基因匹配Match (lcs转lis lcs(nlogn))

基因匹配Match 内存限制:256 MiB 时间限制:1000 ms 标准输入输出 题目描述 基因匹配(match) 卡卡昨天晚上做梦梦见他和可可来到了另外一个星球,这个星球上生物的DNA序列由无数种碱基排列而成(地球上只有4种),而更奇怪的是,组成 DNA序列的每一种碱基在该序列中正好出现5次!这样如果一个DNA序列有N种不同的碱基构成,那么它的长度一定是5N. 卡卡醒来后向可可叙述了这个奇怪的梦,而可 可这些日子正在研究生物信息学中的基因匹配问题,于是他决定为这个奇怪星球上的生物写一个简单

动态时间归整/规整/弯曲(Dynamic time warping,DTW)

动态时间规整DTW 在日常的生活中我们最经常使用的距离毫无疑问应该是欧式距离,但是对于一些特殊情况,欧氏距离存在着其很明显的缺陷,比如说时间序列,举个比较简单的例子,序列A:1,1,1,10,2,3,序列B:1,1,1,2,10,3,如果用欧氏距离,也就是distance[i][j]=(b[j]-a[i])*(b[j]-a[i])来计算的话,总的距离和应该是128,应该说这个距离是非常大的,而实际上这个序列的图像是十分相似的,这种情况下就有人开始考虑寻找新的时间序列距离的计算方法,然后提出了DT

bzoj1264

lcs+dp 用树状数组维护 最大值 1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<ctime> 5 #include<cstdlib> 6 #include<iostream> 7 #include<algorithm> 8 #include<vector> 9 #define lowbit(a) ((a)&(-

背包九讲(转载)

转载 背包问题 //0 1背包 #include<iostream> #include<stdio.h> #include<string.h> using namespace std; int main() { int i,j,n,v,f[1100],w[1100],p[1100]; scanf("%d",&t); while(t--) { memset(f,0,sizeof(f)); scanf("%d%d",&

动态规划-时间规整算法

在日常的生活中我们最经常使用的距离毫无疑问应该是欧式距离,但是对于一些特殊情况,欧氏距离存在着其很明显的缺陷,比如说时间序列,举个比较简单的例子,序列A:1,1,1,10,2,3,序列B:1,1,1,2,10,3,如果用欧氏距离,也就是distance[i][j]=(b[j]-a[i])*(b[j]-a[i])来计算的话,总的距离和应该是128,应该说这个距离是非常大的,而实际上这个序列的图像是十分相似的,这种情况下就有人开始考虑寻找新的时间序列距离的计算方法,然后提出了DTW算法,这种方法在语

POJ2778 DNA Sequence Trie+矩阵乘法

题意:给定N个有A C G T组成的字符串,求长度为L的仅由A C G T组成的字符串中有多少个是不含给定的N个字符串的题解: 首先我们把所有的模式串(给定的DNA序列)建Trie,假定我们有一个匹配串,并且在匹配过程到S[i]这个字符时匹配到了Trie上的某个节点t,那么有两种可能: 匹配失败:t->child[S[i]]为空,跳转到t->fail,因此t->fail一定不能是某个模式串的结尾: 匹配成功:跳转到t->child[S[i+1]],因此t->child[S[i

DNA Pairing

DNA 链缺少配对的碱基.依据每一个碱基,为其找到配对的碱基,然后将结果作为第二个数组返回. Base pairs(碱基对) 是一对 AT 和 CG,为给定的字母匹配缺失的碱基. 在每一个数组中将给定的字母作为第一个碱基返回. 例如,对于输入的 GCG,相应地返回 [["G", "C"], ["C","G"],["G", "C"]] 字母和与之配对的字母在一个数组内,然后所有数组再被组织