HDOJ 1671 Phone List 字典树
http://acm.hdu.edu.cn/showproblem.php?pid=1671
解析:还是字典树的练习,可以利用endFlag来指示数中的节点是不是手机号的最后一位。
如先插入911,这时第二个1的endFlag就是true,再插入911xxxxxx的时候,插完91,发现第三个1也存在并且endFlag为true,直接返回0;
如先插入911xxxxx,后插入911,则在插911的时候,插完91之后发现第二个1这个节点也存在,但是此时i=len-1,说明911是已插入某个手机号的前缀,返回0。
#include <iostream> #include <fstream> #include <vector> #include <string> #include <algorithm> #include <map> #include <stack> #include <cmath> #include <queue> #include <set> #include <list> #include <cctype> #include <stdio.h> #include <stdlib.h> #include <string.h> #define REP(i,j,k) for(int i = j ; i < k ; ++i) #define MAXV (1000) #define INF (0x6FFFFFFF) using namespace std; typedef struct TNode { struct TNode *next[10]; bool endFlag;//指示本位号码是否是手机号最后一位 } TNode; TNode *root; int Insert(char *str) { int len=strlen(str); TNode *p=root; REP(i,0,len) { if(p->next[str[i]-'0']!=NULL)//如果节点存在,访问下一个节点 { p=p->next[str[i]-'0']; if(p->endFlag||i==len-1)//如果下一个节点是之前存入的手机号的最后一位或者是要存的手机号的最后一位则返回0 return 0; } else { p->next[str[i]-'0']=(TNode*)malloc(sizeof(TNode)); p=p->next[str[i]-'0']; REP(j,0,10) { p->endFlag=false; p->next[j]=NULL; } } if(i==len-1)//最后一位置为true p->endFlag=true; } return 1; } void fcuk(TNode *X) {//释放内存 REP(i,0,10) { if(X->next[i]!=NULL) fcuk(X->next[i]); } free(X); } int main() { //freopen("in.txt","r",stdin); int t,n; char num[15]; while(~scanf("%d",&t)) { while(t--) { root=(TNode*)malloc(sizeof(TNode)); REP(i,0,10) { root->next[i]=NULL; root->endFlag=false; } int cnt=0; scanf("%d",&n); REP(i,0,n) { scanf("%s",num); cnt+=Insert(num); } if(cnt==n) printf("YES\n"); else printf("NO\n"); fcuk(root); } } return 0; }