csu 1987: 绚丽的手链
Posted 极速快码
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\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 }
以上是关于csu 1987: 绚丽的手链的主要内容,如果未能解决你的问题,请参考以下文章