Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 18217 Accepted Submission(s): 6120
题目链接:HDU 1671
嗯还是一道简单的Trie,但是对于内存的要求比较高= =不管是malloc或new出来的,用完一定要释放不然……MLE数次。说是Trie其实是学习一下如何进行有效率地释放……
注意题目中可能给的单词顺序不同会出现两种存在前缀的情况
例1、输入911 后输入911000,这个比较简单,逐一插入911000的时候若节点存在则检查是否此时的节点的flag为true即这个节点是一个结尾点。
例2、输入911000 后输入911,办法有很多,我是用一个any来记录后面的911插入时是否出现过未出现的字母,显然在节点不存在new的时候any就要变成1了。
代码:
#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
const int N=10;
const int M=15;
struct Trie
{
Trie *nxt[N];
bool flag;
Trie()
{
for (int i=0; i<N; ++i)
nxt[i]=NULL;
flag=false;
}
};
Trie *L;
bool update(char s[])
{
int i,len=strlen(s);
int indx;
bool is_end=false;
bool any=false;//至少存在一个没出现过的单词
Trie *cur=L;
for (i=0; i<len; ++i)
{
indx=s[i]-‘0‘;
if(!cur->nxt[indx])
{
Trie *one=new Trie();
any=true;
cur->nxt[indx]=one;
cur=one;
}
else
{
cur=cur->nxt[indx];
if(cur->flag)//过程中遇到结尾单词,前缀存在
is_end=true;
}
}
if(!any)
is_end=true;
cur->flag=true;
return is_end;
}
void deleTrie(Trie *L)
{
Trie *cur=L;
for (int i=0; i<N; ++i)
if(cur->nxt[i])
deleTrie(cur->nxt[i]);
delete cur;
}
char s[M];
int main(void)
{
int tcase,n;
scanf("%d",&tcase);
while (tcase--)
{
bool flag=true;
L=new Trie();
scanf("%d",&n);
while (n--)
{
scanf("%s",s);
if(flag)
{
if(update(s))
flag=false;
}
}
puts(flag?"YES":"NO");
deleTrie(L);
}
return 0;
}
HDU 1671 Phone List(Trie的应用与内存释放)
原文:http://www.cnblogs.com/Blackops/p/5911124.html