loj 1224 - DNA Prefix

来源:互联网 发布:手机变成电脑桌面软件 编辑:程序博客网 时间:2024/05/17 20:24

题目链接

题目描述很简单  有n和DNA序列,求出他们中公共前缀长度和有相同公共前缀DNA序列乘积的最大值。

If we take the subset {ACGT} then the result is 4 (4 * 1), if we take {ACGT, ACGTGCGT, ACGCCGT} then the result is 3 * 3 = 9 (since ACG is the common prefix), if we take {ACGT, ACGTGCGT, ACCGTGC, ACGCCGT} then the result is 2 * 4 = 8.

    这个就是英文的描述,很简单,就不翻译了。

思路:

     这个题目明显用trie做,我是这样想的,用trie存储所有的DNA序列,然后每个节点有个cnt值,表示的是存储以该节点结尾的DNA序列的数目。

     在输入过程中便开始建树的过程,最后,在查询结果的时候我用了递归的方式,代码比较好写,也容易理解。

     还有最后一点,虽然我们在竞赛中很少使用指针,但涉及到指针,在用完后一定要释放,否则会MLE,我就MLE两次。

代码:

#include <stdio.h>#include <string.h>#include <algorithm>using namespace std;struct trie{    struct trie *next[5];    int cnt;} *p;trie* newtrie(){    trie *q = new trie();    for (int i = 0; i < 4; i++)        q->next[i] = NULL;    q->cnt = 0;    return q;};void insert(char *str, trie *root){    p = root;    while (*str)    {        int pos;        if (*str == 'A')            pos = 0;        else if (*str == 'C')            pos = 1;        else if (*str == 'G')            pos = 2;        else            pos = 3;        if (!p->next[pos])        {            p->next[pos] = newtrie();            p = p->next[pos];            p->cnt++;        }        else        {            p = p->next[pos];            p->cnt++;        }        str++;    }}int maxnum(struct trie *q, int d){    int maxn = d * q->cnt;    for (int i = 0; i < 4; i++)    {        if (q->next[i])        {            maxn = max(maxn, maxnum(q->next[i], d+1));        }    }    return maxn;}void moveit(trie *root){    if (root == NULL)        return;    for (int i = 0; i < 4;i++)    {        moveit(root->next[i]);    }    free(root);}int main(){    int t, n;    char s[55];    scanf("%d",&t);    for(int k = 1; k <= t; k++)    {        trie *root = newtrie();        scanf("%d",&n);        while (n--)        {            scanf("%s",s);            insert(s, root);        }        printf("Case %d: %d\n", k, maxnum(root, 0));        moveit(root);    }    return 0;}

原创粉丝点击