poj 2945 Find the Clones

https://vjudge.net/problem/POJ-2945

题意:

给出n个长度相同的DNA序列,如果一个DNA序列出现过两次,那么就有说明它被复制了一次。问被复制0次,1次,2次……n-1次的DNA序列分别有多少个。

思路:

可以利用字典树的方法做,用map目测会超时。因为一个字符串是它自己本身的假前缀,所以把每一个字符串的前缀数量-1,就是它被复制的数目。这题学到了一个技巧,统计的时候,已经统计过的要跳开,一开始用map判断超时了,之后想到用sort对char类型的字符串进行排序,但是sort是不能对char的字符串进行排序。但是,我们有结构体啊,把字符串封装在一个结构体中,自己写一个cmp函数就完美的解决了这个问题。这题还是字典树模板用上啦。一定记住最后要释放内存啊。QAQ

代码:

  1 #include <stdio.h>
  2 #include <string.h>
  3 #include <algorithm>
  4 using namespace std;
  5 
  6 int a[20005];
  7 
  8 const int maxn = 26;
  9 
 10 struct str
 11 {
 12     char s[25];
 13 }b[20005];
 14 
 15 bool cmp(str aa,str bb)
 16 {
 17     return strcmp(aa.s,bb.s) < 0;
 18 }
 19 
 20 struct trie
 21 {
 22     trie *next[maxn];
 23 
 24     int flag;
 25 
 26     trie()
 27     {
 28         flag = 1;
 29         memset(next,NULL,sizeof(next));
 30     }
 31 }*root;
 32 
 33 void insert(char *str)
 34 {
 35     int len = strlen(str);
 36     trie *p = root,*q;
 37 
 38     for (int i = 0;i < len;i++)
 39     {
 40         int id = str[i] - 'A';
 41 
 42         if (p -> next[id] == NULL)
 43         {
 44             q = new trie();
 45             p -> next[id] = q;
 46             p = p -> next[id];
 47         }
 48         else
 49         {
 50             p = p->next[id];
 51 
 52             ++(p->flag);
 53         }
 54     }
 55 }
 56 
 57 int query(char *str)
 58 {
 59     int len = strlen(str);
 60     trie *p = root;
 61 
 62     for (int i = 0;i < len;i++)
 63     {
 64         int id = str[i] - 'A';
 65 
 66         p = p -> next[id];
 67 
 68         if (p == NULL) return 0;
 69     }
 70 
 71     return p->flag;
 72 }
 73 
 74 void Free(trie* t)
 75 {
 76     if (t == NULL) return;
 77 
 78     for (int i = 0;i < maxn;i++)
 79     {
 80         if (t -> next[i]) Free(t->next[i]);
 81     }
 82 
 83     delete(t);
 84 }
 85 
 86 
 87 
 88 int main()
 89 {
 90     int n,m;
 91 
 92     while (scanf("%d%d",&n,&m) != EOF)
 93     {
 94         if (m == 0 && n == 0) break;
 95 
 96         memset(a,0,sizeof(a));
 97 
 98         root = new trie();
 99 
100         for (int i = 0;i < n;i++)
101         {
102             scanf("%s",b[i].s);
103             insert(b[i].s);
104         }
105 
106         sort(b,b+n,cmp);
107 
108         //for (int i = 0;i < n;i++)
109             //printf("%s\n",b[i].s);
110 
111         int rs = query(b[0].s);
112 
113         char ss[25];strcpy(ss,b[0].s);
114 
115         a[rs-1]++;
116 
117         for (int i = 1;i < n;i++)
118         {
119             if (strcmp(ss,b[i].s) == 0) continue;
120 
121             strcpy(ss,b[i].s);
122 
123             rs = query(b[i].s);
124 
125             a[rs-1]++;
126         }
127 
128 
129         for (int i = 0;i < n;i++)
130         {
131             printf("%d\n",a[i]);
132         }
133 
134         Free(root);
135     }
136 
137     return 0;
138 }

 

posted @ 2017-07-28 10:32  qrfkickit  阅读(271)  评论(0编辑  收藏  举报