|
1426. Phone List
| |||||||||
| |||||||||
|
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: 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 下面这个程序用时0.24,关键是动态分配耗时比较多,且使用两个指针,空间也不理想,解决办法为申请一块数组, TreeNode data[1000000], 每次分配时不用new,而直接映射到数组就好,这样用时为0.07秒(已测试),大大提高(这种方法对于这道题的确很好, 不过数组开多大,你自己试罗,我60009就过 样例如此而已) #include<iostream>
#include<string.h>
#include<stdlib.h>
using namespace std;
class TreeNode;
typedef TreeNode *Tree;
typedef Tree Position;
/* Implementation */
class TreeNode{
public:
Tree DownTree;
Tree RightTree;
char digt;
TreeNode()
{
DownTree = RightTree = NULL;
}
};
/*
*用法:int (char* PhoneNum, Tree Root)
*以Root为根往下初始化一棵树,数的每个节点以PhoneNum[0]给digt赋值
*若根不为空,则在根的右树初始化
*/
Tree& ini(char PhoneNum[],Tree& Root)
{
if(Root != NULL) //根不为空
return ini(PhoneNum, Root->RightTree);
if(PhoneNum[0] == '/0') //树建立完毕,返回NULL
return Root;
//否则,继续建立下一级树DownTree
Root =new TreeNode;
Root->digt = PhoneNum[0];
ini(&PhoneNum[1], Root->DownTree);
}
/*
*使用:Find(char item, Tree Cur)
*在Cur所在的这一级树进行查找item
*若找到,返回所在位置的指针,否则,返回NULL
*/
inline Position& FindInSameLevel(char& item, Tree& Cur)
{
if(Cur == NULL) //Cur为空,该级未初始化,返回空指针
return Cur;
do{ //否则,沿着DownTree查找
if(Cur->digt == item)
return Cur;
else
Cur = Cur->RightTree;
}
while(Cur != NULL);
return Cur;
}
/*
*用法:isPrefix(char PhoneNum[], Tree Root)
*判断以Root为根的数是否存在前缀现象
*若有,返回True
*否则,返回false
*/
bool isPrefix(char PhoneNum[], const Tree& Root)
{
Tree Cur = Root;bool flag = false; //flag is true if there's prefix
for(int i=0; i < strlen(PhoneNum); i++)
{
Tree tmpCur = Cur; //记录Cur,若Cur被定为为NULL,则对其重定位
if(FindInSameLevel(PhoneNum[i], Cur))
{
flag = true; //找到一个对应的就可以把flag设置为true
if(FindInSameLevel(PhoneNum[i], Cur)->DownTree != NULL) //找到,且该点不为末端
{
Cur = FindInSameLevel(PhoneNum[i], Cur)->DownTree;
continue;
}
else
return true; //该点为末端,树中数据为PhoneNum前缀
}
else //找不到该点,则初始化一棵树
{
Cur= tmpCur ;
flag = false;
ini(&PhoneNum[i], Cur->RightTree);
break; //初始化完了则继续处理下一个号码,不判断flag
}
}
if(flag)
return true;
else
return false;
}
int main()
{
int TestCase;
cin>>TestCase;
while( TestCase-- )
{
int NumofPhoneNum;
cin>>NumofPhoneNum;
Tree Root;
Root = NULL;bool flag;
flag= true; //true 如果没前缀
for(int i=0; i< NumofPhoneNum; i++)
{
char PhoneNum[10];
cin>>PhoneNum;
if(i == 0)
{
ini(PhoneNum, Root); //初始化第一个号码
}
else
if(isPrefix(PhoneNum, Root)) //判断后面输入的号码是否构成前缀
{
flag = false;
char rubbish[10];
for(int j=0; j < NumofPhoneNum - i-1; j++)//构成了前缀,继续接收完剩余的PhoneNum
cin>>rubbish;
cout<<"NO"<<endl;
break;
}
}
if(flag) //不构成,输出YES
cout<<"YES"<<endl;
}
return 0;
}
|
本文介绍了一种用于检查电话号码列表一致性的算法。通过构建树结构并利用指针操作,实现了对输入电话号码列表的高效检查。文章详细阐述了算法实现过程、时间复杂度优化方法,并提供了样例输入输出,旨在帮助读者理解和实现电话号码一致性检查。
Copy sample input to clipboard
1405

被折叠的 条评论
为什么被折叠?



