light OJ -DNA Prefix (字典树)

来源:互联网 发布:成都生活家装饰 知乎 编辑:程序博客网 时间:2024/05/21 06:45

题目链接:

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=121897#problem/G

题目大意:

寻找所给字符串的 前缀*出现次数 的最大值

题解:

字典树,v[u]为结点出现次数,存字符串后利用搜索不断遍历所有有字母的点,找到最大值。此题因为只有4个字母,所以字典树的宽度应为4,如果为26会超出内存。

AC代码:

#include <cstdio>#include <algorithm>#include <cstring>#include <cctype>#include <iostream>using namespace std;const int maxnode = 2500500;const int sigma   = 4;int ch[maxnode][sigma],v[maxnode],sz,ans;int u;int maxx;int numb[maxnode];struct trie{    trie()    {        sz=1;        memset(v,0,sizeof v);        memset(ch[0],0,sizeof ch[0]);    }    int idx(char c)//如果不这样存的话会爆内存    {        if(c == 'C')            return 1;        else if(c == 'G')            return 2;        else if(c == 'T')            return 3;        return 0;    }    void insert(char* s)    {        int l =strlen(s);        u=0;        for(int i=0;i<l;i++)        {            int c = idx(s[i]);            if(!ch[u][c])            {                v[sz] = 0;                memset(ch[sz],0,sizeof ch[sz]);                ch[u][c] = sz++;                //cout << ch[u][c] <<endl;            }            u = ch[u][c];            v[u] ++;        }    }    void solve(int u, int d)//搜索寻找最大值,d为前缀长度    {        ans = max(ans, d * v[u]);        for (int i = 0; i < 4; i++)        {            if (ch[u][i])                solve(ch[u][i], d + 1);        }    }}T;int n,m;char c[105];int main(){    int TTT;    int cnt = 1;    cin >> TTT;    while(TTT--)    {        int nnn;        cin >> nnn;        while(nnn--)        {            scanf("%s" , c);            T.insert(c);        }        ans = 0;        T.solve(0,0);        printf("Case %d: %d\n", cnt++, ans);        sz=1;        memset(v,0,sizeof v);        memset(ch[0],0,sizeof ch[0]);    }    return 0;}
0 0
原创粉丝点击