• 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
    ",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
    ",a[i]);
    132         }
    133 
    134         Free(root);
    135     }
    136 
    137     return 0;
    138 }
  • 相关阅读:
    第二十八节-3d 盒子(transform transition )炫酷操作
    第二十七节-动画animation以及与transform的冲突
    第二十六节-transform
    transition的属性与使用,绝对定位初始值要设0,以及淡入淡出,消失
    阿里图标与iframe框架
    第二十二节-表格
    第二十一节-表单元素2以及input一些使用习惯和伪类 点击按钮换图片且有淡入淡出的效果
    第二十节-重要表单(form 与 input) 、label 标签
    案例-京东小按钮
    复合写法需要注意的
  • 原文地址:https://www.cnblogs.com/kickit/p/7248890.html
Copyright © 2020-2023  润新知