csu 1987: 绚丽的手链

1987: 绚丽的手链

Submit Page   Summary   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\n",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 }
时间: 2024-10-10 08:00:51

csu 1987: 绚丽的手链的相关文章

CSU 1804: 有向无环图(拓扑排序)

http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1804 题意:…… 思路:对于某条路径,在遍历到某个点的时候,之前遍历过的点都可以到达它,因此在这个时候对答案的贡献就是∑(a1 + a2 + a3 + ... + ai) * bv,其中a是之前遍历到的点,v是当前遍历的点. 这样想之后就很简单了.类似于前缀和,每次遍历到一个v点,就把a[u]加给a[v],然后像平时的拓扑排序做就行了. 1 #include <bits/stdc++.h>

CSU 1111: 三家人【有趣的思维题】

1111: 三家人 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 2241  Solved: 874 [Submit][Status][Web Board] Description 有三户人家共拥有一座花园,每户人家的太太均需帮忙整理花园.A 太太工作了5 天,B 太太则工作了4 天,才将花园整理完毕.C 太太因为正身怀六甲无法加入她们的行列,便出了90元.请问这笔钱如何分给A.B 二位太太较为恰当?A 应得多少元?90/(5+4)*5=$50

CSU 1112: 机器人的指令【模拟题】

1112: 机器人的指令 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 1858  Solved: 682 [Submit][Status][Web Board] Description 数轴原点有一个机器人.该机器人将执行一系列指令,你的任务是预测所有指令执行完毕之后它的位置. ·LEFT:往左移动一个单位 ·RIGHT: 往右移动一个单位 ·SAME AS i: 和第i 条执行相同的动作.输入保证i 是一个正整数,且不超过之前执行指令数 In

CSU 1416 Practical Number

原题链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1416 结论题,具体判断方法请点击这个网址. 筛素数是肯定的,但一开始定的范围太大了,想当然要筛到10^9的质数,但仔细想想,只要到sqrt(10^9)就可以了,最后的那一个质数是最后一步的比较,不用筛出来. #include <stdio.h> #include <string.h> #include <iostream> using namespace st

CSU 1412 Line and Circles

原题链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1412 题目要求判断是否有一条直线可以穿过所有的圆. 做法:把所有圆心做一次凸包,然后判断这个凸包是否能通过一个宽度为2*R的通道. 做法和求凸包直径差不多,只是判断的时候把点到两个端点的距离换成点到直线的距离. #include <stdio.h> #include <string.h> #include <math.h> #include <stdli

CSU 1547 Rectangle(dp、01背包)

题目链接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1547 Description Now ,there are some rectangles. The area of these rectangles is 1* x or 2 * x ,and now you need find a big enough rectangle( 2 * m) so that you can put all rectangles into it(th

CSU 1601 War (并查集)

1601: War Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 202  Solved: 58 [Submit][Status][Web Board] Description AME decided to destroy CH's country. In CH' country, There are N villages, which are numbered from 1 to N. We say two village A and B ar

CSU - 1542 Flipping Parentheses (线段树)

CSU - 1542 Flipping Parentheses Time Limit: 5000MS   Memory Limit: 262144KB   64bit IO Format: %lld & %llu Submit Status Description Input Output Sample Input 6 3 ((())) 4 3 1 Sample Output 2 2 1 Hint 题意:先给出一个符合括号匹配的字符串,然后Q次操作 每次操作将某个括号反转,问将哪个括号反转能使字

POJ 1987 Distance Statistics (树上点分治)

题目地址:POJ 1987 点分治模板题,跟POJ 1741几乎一样,.. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <algorithm> #include <stdlib.h> #include <map> #include <set> #include <stdi