hdu1671 Phone List

这个题目可以用两种方法:首先都是将电话号码打成字典树,然后第一种方法就是记录下每次输入的号码,然后另外从头到尾将每一个电话号码都进行查找,看是否有前缀存在,这种方法无论从时间、空间都不优化,第二种方法相对好点,建树之时标记一下当前节点的下一个节点是否存在(当前串为之前串的前缀)以及是否有串在当前串之前就出现过(之前串是否为当前串的前缀),然后遍历查找时,每插入一个电话号码就对当前输入的电话号码进行查找,如果出现上述两种情况就可以判定为NO,PS:记得回收内存。。。

方法二:

#include <iostream>
using namespace std;
struct Trie
{
       bool num;
       bool end;
       Trie *son[10];
       Trie(){
              for (int i = 0; i < 10; i ++){
                  son[i] = NULL;   
              }      
              end = num = false;
       }    
};
void insert(char *a, Trie *root)
{
     int len = strlen(a);
     Trie *temp = root;
     for (int i = 0; i < len; i ++){
         int k = a[i] - '0';
         if (temp -> son[k] == NULL){
            temp -> son[k] = new Trie;        
         }   
         temp -> num = true;
         temp = temp -> son[k];
     }    
     temp -> end = true;
}
char alp[11];
bool find(char *a, Trie *root)
{
     Trie *temp = root;
     int len = strlen(a);
     int i;
     for (i = 0; i < len; i ++){
         int k = a[i] - '0';
         if (temp -> end)return true;//如果之前有串为当前输入串的前缀
         temp = temp -> son[k];
     }
     if (temp -> num)return true;//如果当前串为之前串的前缀
     return false;
}
void dele(Trie *root)//记得回收内存,防止超内存
{
    for (int i = 0; i < 10; i ++){
        if (root -> son[i] != NULL){
           dele(root -> son[i]);        
        }   
    }   
    free(root);
}
int main()
{
    int t;
    scanf("%d", &t);
    while (t --){
          int n1;
          int n = 0;
          scanf("%d", &n1);
          getchar();
          Trie *root;
          root = new Trie;
          bool check = false;
          int st = false;
          while (n1 --){
                scanf("%s", alp);
                if (!check){//如果WA,就写下这句话,因为check的true可能被之后的false覆盖掉导致错误
                   insert(alp, root);
                   check = find(alp, root);
                }
          }
          if (check)printf("NO\n");
          else printf("YES\n");
          dele(root);
    }
    return 0;   
}

方法一:

#include <iostream>
using namespace std;
struct Trie
{
       int num;
       int end;
       Trie *son[26];
       Trie(){
              for (int i = 0; i < 26; i ++){
                  son[i] = NULL;   
              }      
              end = num = 0;
       }    
};
void insert(char *a, Trie *root)
{
     int len = strlen(a);
     Trie *temp = root;
    
     for (int i = 0; i < len; i ++){
         int k = a[i] - '0';//cout<<"asasd"<<endl;
         if (temp -> son[k] == NULL){
            temp -> son[k] = new Trie;        
         }   
         temp = temp -> son[k];
         temp -> num ++;
        
     }    
     temp -> end ++;
}
char alp[10010][11];
bool find(char *a, Trie *root)
{
     Trie *temp = root;
     int len = strlen(a);
     int i;
     for (i = 0; i < len; i ++){
         int k = a[i] - '0';
         int b = temp -> num;
         int end = temp -> end;
         temp = temp -> son[k];
         if (b != temp -> num && end)return true;
     }
     return false;
}
void dele(Trie *root)
{
    for (int i = 0; i < 10; i ++){
        if (root -> son[i] != NULL){
           dele(root -> son[i]);        
        }   
    }   
    free(root);
}
int main()
{
    int t;
    scanf("%d", &t);
    while (t --){
          int n1;
          int n = 0;
          scanf("%d", &n1);
          getchar();
          Trie *root;
          root = new Trie;
          while (n1 --){
                scanf("%s", alp[n ++]);
                insert(alp[n-1], root);     
          }
          bool check = false;
          for (int i = 0; i < n; i ++){
              check = find(alp[i], root);
              if (check)break;
          }
          if (check)printf("NO\n");
          else printf("YES\n");
          dele(root);
    }
    return 0;   
}

你可能感兴趣的:(hdu1671 Phone List)