zoukankan      html  css  js  c++  java
  • csu 1987: 绚丽的手链

    1987: 绚丽的手链

            Time Limit: 6 Sec     Memory Limit: 512 Mb     Submitted: 13     Solved: 2    


    Description

    小X的妹妹马上就要过生日了,作为哥哥,小X打算买一些手链送给妹妹。

    采购完礼物回到家的小X惊奇的发现:每条手链虽然只由两种颜色的珠子串成,但是它们有一个神奇的效果,那就是当多条手链同时放在一起时,会散发出绚丽夺目的光芒。光芒的绚丽程度有强有弱,这取决于手链的最长公共前缀的长度和手链数目的乘积。例如000,001,0011三串手链放在一起会发出绚丽程度为6的光芒。

    显然如果将所有手链都送给妹妹,效果未必最好,因此他决定从中挑选一些送给妹妹,使得能够达到最绚丽的效果。你能帮助他吗?

    Input

    第一行一个整数 T (≤ 20) 表示数据组数。

    每组数据第一行一个整数 n(≤ 50000) 代表字符串的数量。接下来N行,每行为一个仅由0,1组成的字符串代表小X购买的手链,手链的最大长度为200。

    Output

    对于每组数据输出一行, 表示小X经过挑选后送给妹妹的手链所能产生的最大绚丽程度。

    Sample Input

    4
    4
    0000
    0001
    10101
    010
    2
    01010010101010101010
    11010010101010101010
    3
    010101010101000010001010
    010101010101000010001000
    010101010101000010001010
    5
    01010101010100001010010010100101
    01010101010100001010011010101010
    00001010101010110101
    0001010101011010101
    00010101010101001 

    Sample Output

    6
    20
    66
    44 

    Hint

    Source

    2017年暑期集训校队选拔

    Author

    徐戍

    题解:

    这个题目是真的不好做    心累

    6次超时   还有几次其他的错误    

    我的第一想法就是   构建字典树  节点记录下着是几个字符串的公共子串   (这个不难)  然后就是一次遍历字典树   求出答案   结果超时

    然后  我发现建树之后其实不用去遍历了    我们在建树的时候   就可以得到答案    结果还是超时

    下面的超时的那个代码    各位大佬谁会优化的   告诉一下我怎么优化   0.0    (后面有AC代码)

     1 #include <cstdio>
     2 #include <time.h>
     3 #include <cmath>
     4 #include <map>
     5 #include <stdlib.h>
     6 #include <cstring>
     7 using namespace std;
     8 char s[205];
     9 int ans;
    10 struct Trie
    11 {
    12     int num;
    13     struct Trie *nxt[2];
    14     Trie()
    15     {
    16         num=0;
    17         for(int i=0; i<2; i++)
    18         {
    19             nxt[i]=NULL;
    20         }
    21     }
    22 };
    23 
    24 void Trie_Inser(Trie *p,char s[])
    25 {
    26     int i=0;
    27     Trie *q=p;
    28     while(s[i])
    29     {
    30         int nx=s[i]-'0';
    31         if(q->nxt[nx]==NULL)
    32         {
    33             q->nxt[nx]=new Trie;
    34         }
    35         i++;
    36         q=q->nxt[nx];
    37         q->num++;
    38         ans=max(ans,(q->num)*i);
    39     }
    40 }
    41 int main()
    42 {
    43     int n,m;
    44     scanf("%d",&n);
    45     while(n--)
    46     {
    47         ans=0;
    48         Trie *p=new Trie;
    49         scanf("%d",&m);
    50         getchar();
    51         while(m--)
    52         {
    53             gets(s);
    54             Trie_Inser(p,s);
    55         }
    56 
    57                 printf("%d
    ",ans);
    58 
    59     }
    60     return 0;
    61 }

    在我觉得动态字典树的做法没有救了之后    我尝试了一下动态字典树的    说的简单点就是使用数组去模拟   

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 
     5 using namespace std;
     6 int pos,ans;
     7 struct node
     8 {
     9     int num;
    10     int child[2];
    11 }tree[10000010];
    12 
    13 int add()
    14 {
    15     pos++;
    16     tree[pos].num=0;
    17     for(int i=0;i<2;i++)
    18     {
    19         tree[pos].child[i]=-1;
    20     }
    21     return pos;
    22 }
    23 
    24 int inser(char* str)
    25 {
    26     int post=0;
    27     int tmp=0;
    28     int len=strlen(str);
    29     for(int i=0;i<len;i++)
    30     {
    31         int m=str[i]-'0';
    32         if(tree[post].child[m]==-1)
    33         {
    34             if(tmp==0)
    35                 tmp=i+1;
    36             tree[post].child[m]=add();
    37         }
    38 
    39         post=tree[post].child[m];
    40         tree[post].num++;
    41           ans=max(ans,tree[post].num*(i+1));
    42     }
    43     if(!tmp)
    44         tmp=len;
    45     return tmp;
    46 }
    47 
    48 char arr[1000010];
    49 int main()
    50 {
    51     int T;
    52     scanf("%d",&T);
    53     for(int t=1;t<=T;t++)
    54     {
    55         int n;
    56         pos=0;
    57         memset(tree[0].child,-1,sizeof(tree[0].child));
    58         scanf("%d",&n);
    59         ans=0;
    60         for(int i=0;i<n;i++)
    61         {
    62             scanf("%s",&arr);
    63             int k=inser(arr);
    64         }
    65         cout<<ans<<endl;
    66     }
    67     return 0;
    68 }
  • 相关阅读:
    64位ubuntu中chrome浏览器安装Adobe Flashplayer插件
    DirectX SDK 重大版本变化记录[转]
    DirectX SDK版本与Visual Studio版本 [转]
    C#正则表达式整理备忘[转]
    NPOI 设置单元格边框
    C# Winform DirectX视频播放器
    C#压缩指定的文件并生成zip文件
    maple 15 数学图形绘制软件[VeryCD]
    VWG部署到64位win7系统的关键
    VWG网页下载时中文乱码的解决方法
  • 原文地址:https://www.cnblogs.com/52why/p/7460121.html
Copyright © 2011-2022 走看看