hihocoder-1551-合并子目录
#1551 : 合并子目录
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
小Hi的电脑的文件系统中一共有N个文件,例如:
/hihocoder/offer22/solutions/p1
/hihocoder/challenge30/p1/test
/game/moba/dota2/uninstall
小Hi想统计其中一共有多少个不同的子目录。上例中一共有8个不同的子目录:
/hihocoder
/hihocoder/offer22
/hihocoder/offer22/solutions
/hihocoder/challenge30
/hihocoder/challenge30/p1
/game
/game/moba
/game/moba/dota2/
输入
第一行包含一个整数N (1 ≤ N ≤ 10000)
以下N行每行包含一个字符串,代表一个文件的绝对路径。保证路径从根目录"/"开始,并且文件名和目录名只包含小写字母和数字。
对于80%的数据,N个文件的绝对路径长度之和不超过10000
对于100%的数据,N个文件的绝对路径长度之和不超过500000
输出
一个整数代表不同子目录的数目。
- 样例输入
-
3 /hihocoder/offer22/solutions/p1 /hihocoder/challenge30/p1/test /game/moba/dota2/uninstall
- 样例输出
-
8
题解:
知道是使用 Trie 树来解决, 但是自己做的面对 char的, 应该使用 STL,将 string 组装进 STL 进行 Trie 树的搜索才是。
AC code。
#include <unordered_map> #include <string> #include <iostream> using namespace std; struct Trie{ unordered_map<string, Trie*> mp; }; int main(){ int n, cnt; while(cin >> n){ string s; Trie *root = new Trie(); cnt = 0; for(int i=0; i<n; ++i){ cin >> s; Trie *tmp = root; size_t sd = 1, fd = s.find('/', sd); while(fd != string::npos){ string t = s.substr( sd, fd - sd ); if(tmp->mp.find( t ) == tmp->mp.end() ){ tmp->mp[ t ] = new Trie(); ++cnt; } tmp = tmp->mp[ t ]; sd = fd + 1; fd = s.find('/', sd); } } cout << cnt << endl; } return 0; }
My own Memory Limit Exceed Code。
我使用的是面对 ch 进行建树节点,有很多多余的节点。导致了 Memory Limit Exceeded。
#include <cstdio> #include <cstring> const int MAXN = 500000; struct Node{ char ch; Node *next[75]; Node(char _ch){ ch = _ch; for(int i=0; i<75; ++i){ next[i] = NULL; } } }; int cnt; Node *root = new Node('/'); void insert_ch(char ch[], int len){ Node *tmp = root; for(int i=1; i<len; ++i){ if(tmp->next[ ch[i] - '/' ] == NULL){ tmp->next[ ch[i] - '/' ] = new Node(ch[i]); if( ch[i] == '/' ){ cnt++; } } tmp = tmp->next[ ch[i] - '/' ]; } } int main(){ int n; while(scanf("%d", &n) != EOF){ cnt = 0; char ch[MAXN]; for(int i=0; i<n; ++i){ getchar(); scanf("%s", ch); insert_ch(ch, strlen(ch)); } printf("%d ", cnt ); } return 0; }