再谈字典树:HDOJ 1671 Phone List(内存释放)
2015-07-24 19:42
369 查看
前两天刚发了篇博客,讲的是两道简单的字典树,今天无意间看到了这道题,我觉得有必要再来扩充一下我的字典树知识:合理分配动态内存。记得上C++课的时候,老师讲过,用new创建的指针,程序结束后最好都用delete来删除动态内存,不然会造成内存泄露。然而以前做的题虽然内存开的很大,也没在意。看了今天这道,自己也反思了下,像很多网友说的,不要为了AC而AC,虽然说的很那啥,但这确实是值得我思考的。
看一下题吧:
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Problem Description
Given a list of phone numbers, determine if it is consistent in the sense that no number is the prefix of another. Let’s say the phone catalogue listed these numbers:
1. Emergency 911
2. Alice 97 625 999
3. Bob 91 12 54 26
In this case, it’s not possible to call Bob, because the central would direct your call to the emergency line as soon as you had dialled the first three digits of Bob’s phone number. So this list would not be consistent.
Input
The first line of input gives a single integer, 1 <= t <= 40, the number of test cases. Each test case starts with n, the number of phone numbers, on a separate line, 1 <= n <= 10000. Then follows n lines with one unique phone number on each line. A phone number
is a sequence of at most ten digits.
Output
For each test case, output “YES” if the list is consistent, or “NO” otherwise.
Sample Input
2
3
911
97625999
91125426
5
113
12340
123440
12345
98346
Sample Output
NO
YES
题意:给你一组电话,如果里面有一些短的号码(设整个号码为i)和长一点的号码的前i个数字相同,那么电话机会自动拨打那个短号码,所以你就不能往下按了。就是你不能拨打那个长号码了。如果有这种短号码,即不能拨打某个号码,输出NO,否则输出YES;
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
struct Trie{
Trie *next[11];
bool boom;
Trie(){
for(int i=0;i<11;i++)
next[i]=NULL;
boom=true;
}
};
bool flag=true;
void buildAndSearch(char s[],Trie *root){
Trie *now=root;
int len=strlen(s);
for(int i=0;i<len;i++){
if(now->next[s[i]-'0']==NULL)
now->next[s[i]-'0']=new Trie;
else{
if((now->next[s[i]-'0'])->boom==false){
flag=false; break;
}
}
now=now->next[s[i]-'0'];
}
now->boom=false;
for(int i=0;i<11;i++){
if(now->next[i]!=NULL){
flag=false;return;
}
}
}
void freeDom(Trie *now){
for(int i=0;i<11;i++){
if(now->next[i]!=NULL) freeDom(now->next[i]);
}
delete now;
}
int main()
{
int T;
scanf("%d",&T);//scanf("\n");
while(T--){
flag=true;
Trie *root=new Trie;
int N;
scanf("%d",&N);scanf("\n");
char pn[11];
while(N--){
scanf("%s",pn);
buildAndSearch(pn,root);
}
if(flag) printf("YES\n");
else printf("NO\n");
freeDom(root);
}
return 0;
}
注意911(先) 91125426(后) 和 91125426(先) 911(后),输入循序不同要都考虑进去。当然,若是使用那种建树与查询分开的做法,好像是不用讨论的,具体我没试过,最后记得将每次的动态内存删除。
看一下题吧:
Phone List
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Problem Description
Given a list of phone numbers, determine if it is consistent in the sense that no number is the prefix of another. Let’s say the phone catalogue listed these numbers:
1. Emergency 911
2. Alice 97 625 999
3. Bob 91 12 54 26
In this case, it’s not possible to call Bob, because the central would direct your call to the emergency line as soon as you had dialled the first three digits of Bob’s phone number. So this list would not be consistent.
Input
The first line of input gives a single integer, 1 <= t <= 40, the number of test cases. Each test case starts with n, the number of phone numbers, on a separate line, 1 <= n <= 10000. Then follows n lines with one unique phone number on each line. A phone number
is a sequence of at most ten digits.
Output
For each test case, output “YES” if the list is consistent, or “NO” otherwise.
Sample Input
2
3
911
97625999
91125426
5
113
12340
123440
12345
98346
Sample Output
NO
YES
题意:给你一组电话,如果里面有一些短的号码(设整个号码为i)和长一点的号码的前i个数字相同,那么电话机会自动拨打那个短号码,所以你就不能往下按了。就是你不能拨打那个长号码了。如果有这种短号码,即不能拨打某个号码,输出NO,否则输出YES;
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
struct Trie{
Trie *next[11];
bool boom;
Trie(){
for(int i=0;i<11;i++)
next[i]=NULL;
boom=true;
}
};
bool flag=true;
void buildAndSearch(char s[],Trie *root){
Trie *now=root;
int len=strlen(s);
for(int i=0;i<len;i++){
if(now->next[s[i]-'0']==NULL)
now->next[s[i]-'0']=new Trie;
else{
if((now->next[s[i]-'0'])->boom==false){
flag=false; break;
}
}
now=now->next[s[i]-'0'];
}
now->boom=false;
for(int i=0;i<11;i++){
if(now->next[i]!=NULL){
flag=false;return;
}
}
}
void freeDom(Trie *now){
for(int i=0;i<11;i++){
if(now->next[i]!=NULL) freeDom(now->next[i]);
}
delete now;
}
int main()
{
int T;
scanf("%d",&T);//scanf("\n");
while(T--){
flag=true;
Trie *root=new Trie;
int N;
scanf("%d",&N);scanf("\n");
char pn[11];
while(N--){
scanf("%s",pn);
buildAndSearch(pn,root);
}
if(flag) printf("YES\n");
else printf("NO\n");
freeDom(root);
}
return 0;
}
注意911(先) 91125426(后) 和 91125426(先) 911(后),输入循序不同要都考虑进去。当然,若是使用那种建树与查询分开的做法,好像是不用讨论的,具体我没试过,最后记得将每次的动态内存删除。
相关文章推荐
- 深入学习请求响应(一)---response的应用
- Linux内核下进程切换
- Hadoop-2.5伪分布式+Hive-1.0.1+mysql
- App9_06_利用IOException的异常处理
- App9_12_异常的捕获与处理
- HDU 4069 Squiggly Sudoku
- 2015年7月24日笔记
- HDU 1181 变形课
- [INS-06006] Passwordless SSH connectivity not set up
- App8_15_匿名内部类
- 快速学习STL中find函数和replace函数的应用,nyoj,字符串的替换113
- hdu An easy problem (背包)
- hdu Piggy-Bank (背包)
- App8_14_内部类与外部类的访问规则
- 酒肉穿肠过 佛祖心中留...
- App8_12_利用接口实现多重继承
- 安卓实习第八天
- HDOJ 1201 18岁生日(日期与天数计算)
- ZOJ Problem Set - 1007 Numerical Summation of a Series
- 胖大海和罗汉果可以同泡吗