//二维数组+动态内存+释放,需要注意指针数组的使用方法 //和树完全建完后,怎么释放树 //大致题意:多组电话号码,如果存在某组是其他组的前缀则输出NO #include <iostream> #include <string> #include <cstdlib> #include <cstring> #include <cstdio> using namespace std; char *str[10001]; typedef struct Node { int cnt ; Node *child[11]; }Node; void init(Node *root) { int i; for(i=0;i<11;i++) root->child[i] = NULL; root->cnt=0; } void insert(char *s,Node *root)//注意指针数组的传参方式 { Node *current = root; int i; for(i=0;i<s[i]!='\0';i++) { int index = s[i]-'0'; if(current->child[index] != NULL) { current = current->child[index]; (current->cnt)++; } else { Node *newnode = new Node; init(newnode); current->child[index] = newnode; current = newnode; current->cnt =1; } } } bool find (char *s,Node *root) { Node *current = root; int i; /* for(i=0;s[i]!='\0';i++) { int index = s[i]- '0'; if(current->child[index]&¤t->cnt>1) current = current->child[index]; //实际上下面这种情况不可能存在,但为保险起见, //没有直接else //else if(current->child[index]==NULL) // return true; else if(current->cnt=1) return false; } return true; */ for(i=0;s[i]!='\0';i++) { int index = s[i]- '0'; //不必再加上if判断了,必定可以走到末尾,因为他就是树里的串 current = current->child[index]; } if(current->cnt==1) return false; return true; } void My_delete(Node *root) { int i; if(root==NULL) return ; else//加不加else均可AC { for(i=0;i<11;i++) { if(root->child[i]) My_delete(root->child[i]); } } delete root; return ; } int main() { int i,j,k,T; cin>>T; while(T--) { Node *root = new Node; init(root);//开在局部,希望对减小内存有所帮助 int num; cin>>num; memset(str,0,sizeof(str)); i=0; k = num; while(num--) { //用指针数组的话,必须给他申请空间,否则出现内存不可写 str[i]=(char *)malloc(11*sizeof(char)); cin>>str[i]; //gets(str[i]); /* 刚开始这用的是gets,上面cin>>num时, 没有吸收掉换行符会被gets吸收,所以输入少于一行时就输出了结果 换位cin以后就不必加上getchar了,因为cin不接受换行符 */ insert(str[i],root); i++; } //上面的num已经变化,所以下面不可再使用num(num=-1) ,看来以后在内部输入还是用for循环吧 for(j=0;j<k;j++) { bool flag = find (str[j],root); if(flag) { cout<<"NO"<<endl; break; } } if(j==k) cout<<"YES"<<endl; My_delete(root); } return 0; }