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