1. 程式人生 > >csu 1987: 絢麗的手鏈

csu 1987: 絢麗的手鏈

getc can 簡單 產生 csu time sizeof 想法 display

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: 絢麗的手鏈