hdu1671-Phone List 题目链接 典型的字典树,当然,有这么几点要注意,因为有多组测试数据,所以后面一点要记得清空堆,另外,可以从中间就判断是不是出现了重复,不用全部遍历,如果某个电话号码在建立的时候经过的结点的isStr为true,那就结束, 当然还有一种情况不要忘了:如果某个电话号码建立的时候没有创建结点,那么它一定在重复别人的老路,不用说,必须no! code: #include #include #include #include #include #include #include #include #include #include #include #define line 10002 #define row 11 #define MAXX 10 using namespace std; char lr[line][row] ; int flag ; typedef struct TrieNode /**Trie结点声明*/ { bool isStr; /**标记该结点处是否构成单词*/ struct TrieNode *next[MAXX]; /**儿子分支*/ }Trie; void ins(Trie *root,const char *s) /**将单词s插入到字典树中*/ { if(root==NULL||*s=='\0') return; int i; int ka = 1 ; Trie *p=root; while(*s!='\0') { if(p->next[*s-'0']==NULL) /**如果不存在,则建立结点*/ { ka = 0 ; Trie *temp=(Trie *)malloc(sizeof(Trie)); for(i=0;i next[i]=NULL; } temp->isStr=false; p->next[*s-'0']=temp; p=p->next[*s-'0']; } else { ka = 1 ; if( (p->next[*s-'0'])->isStr == true ) /**如果所经路径上存在完结字符串**/ { flag = 0 ; return ; } p=p->next[*s-'0']; } s++; } p->isStr=true; if( ka ){ /**如果路上从来不存在新建结点**/ flag = 0 ; } } void del(Trie *root) /**释放整个字典树占的堆区空间*/ { int i; for(i=0;i next[i]!=NULL) { del(root->next[i]); } } free(root); } int main() { int T ; int n ; int i ; Trie* root ; scanf( "%d%*c" , & T ); while ( T-- ){ root = ( Trie * ) malloc( sizeof(Trie) ) ; for( i = 0 ; i < MAXX ; i++ ){ root -> next[ i ] = NULL ; } i = 0 ; flag = 1 ; scanf( "%d%*c" , & n ) ; while( i < n ){ scanf( "%s" , lr[i++] ); } for( i = 0 ; i < n ; i++ ){ if(flag){ ins ( root , lr[i] ) ; } else{ break ; } } if(flag){ printf( "YES\n" ) ; } else{ printf( "NO\n" ) ; } del ( root ) ; } return 0; }