// [7/5/2014 Sjm] /* 刚开始看到这道题,感觉不是用字典树解决的题,但看到这句知道可能用到字典树: less than 30 digits (只好用字符串保存了) 解题关键: 给定一组非负整数,不断从中选取出当前可以选出的最长的递增序列,组成一个集合,直到所给的非负整数全部取完。 我们发现,集合的个数即所要求的答案。 但是,什么又决定集合的个数呢? 举几个例子,便会发现是所给非负整数中重复最多的那个数。。。(由集合也可以联想到) 故可以用字典树解决。。。 (注意把前导零去掉) */
1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <cstring> 5 #include <cmath> 6 #include <algorithm> 7 using namespace std; 8 const int MAX = 10; 9 10 struct Trie{ 11 int Tcount; 12 Trie* next[MAX]; 13 Trie(){ 14 Tcount = 0; 15 memset(next, NULL, sizeof(next)); 16 } 17 }; 18 19 Trie* Root; 20 21 int CreTrie(char* str) 22 { 23 int len = strlen(str); 24 Trie* p = Root; 25 for (int i = 0; i < len; i++) { 26 int pos = str[i] - '0'; 27 if (!(p->next[pos])) { 28 p->next[pos] = new Trie; 29 } 30 p = p->next[pos]; 31 } 32 p->Tcount++; 33 return (p->Tcount); 34 } 35 36 void DelTrie(Trie* T) 37 { 38 for (int i = 0; i < MAX; i++) { 39 if (T->next[i]) { 40 DelTrie(T->next[i]); 41 } 42 } 43 delete[] T; 44 } 45 46 int main() 47 { 48 //freopen("input.txt", "r", stdin); 49 int N; 50 while (~scanf("%d", &N)) { 51 char str[35]; 52 Root = new Trie; 53 int ans = 0; 54 while (N--){ 55 scanf("%s", str); 56 int len = 0; 57 int i = 0; 58 while (str[i] == '0') { 59 i++; 60 } 61 ans = max(ans, CreTrie(str+i)); 62 }; 63 printf("%d ", ans); 64 DelTrie(Root); 65 } 66 return 0; 67 }