| |
Time Limit: 1sec Memory Limit:64MBDescription 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: • Emergency 911 • Alice 97 625 999 • 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. InputThe 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. OutputFor each test case, output “YES” if the list is consistent, or “NO” otherwise. Sample Input Copy sample input to clipboard2391197625999911254265113123401234401234598346 Sample OutputNOYES 下面這個程式用時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')//樹建立完畢,返回NULLreturn Root;//否則,繼續建立下一級樹DownTreeRoot =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為空白,該級未初始化,返回null 指標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 prefixfor(int i=0; i < strlen(PhoneNum); i++){Tree tmpCur = Cur;//記錄Cur,若Cur被定為為NULL,則對其重定位if(FindInSameLevel(PhoneNum[i], Cur)){flag = true;//找到一個對應的就可以把flag設定為trueif(FindInSameLevel(PhoneNum[i], Cur)->DownTree != NULL)//找到,且該點不為末端{Cur = FindInSameLevel(PhoneNum[i], Cur)->DownTree;continue;}elsereturn true;//該點為末端,樹中資料為PhoneNum首碼}else//找不到該點,則初始化一棵樹{Cur= tmpCur ;flag = false;ini(&PhoneNum[i], Cur->RightTree);break;//初始化完了則繼續處理下一個號碼,不判斷flag}}if(flag)return true;elsereturn 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);//初始化第一個號碼}elseif(isPrefix(PhoneNum, Root)) //判斷後面輸入的號碼是否構成首碼{flag = false;char rubbish[10];for(int j=0; j < NumofPhoneNum - i-1; j++)//構成了首碼,繼續接收完剩餘的PhoneNumcin>>rubbish;cout<<"NO"<<endl;break;}}if(flag)//不構成,輸出YEScout<<"YES"<<endl;}return 0;} |