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;
}