HDOJ 1671 HDU 1671 Phone List ACM 1671 IN HDU

7459 ワード

MiYuオリジナル、転帖は明記してください:転載は______________白い家 から
 
タイトルアドレス:
       http://acm.hdu.edu.cn/showproblem.php?pid=1671  
タイトルの説明:
Phone ListTime Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1733    Accepted Submission(s): 572
Problem Description
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:
1. Emergency 911
2. Alice 97 625 999
3. 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.
 
Input
The 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.
 
Output
For each test case, output “YES” if the list is consistent, or “NO” otherwise.
 
Sample Input

      
        
2 3 911 97625999 91125426 5 113 12340 123440 12345 98346

 
Sample Output

      
        
NO YES

 
  
 
テーマ分析:
この問題にはいろいろな方法があります.大牛は静的辞書の木を使っています.兄はできなくて、ただ動的で、結局MLEは20数回...、私の構造体は局所変数を使っていますが、今でも
なぜ彼が自動的に釈放しないのか分からないが...最後にダイナミック配列の解放を加えてやっとAが落ちる・・・そしてSTLを試してみました…ダイナミック辞書よりも速い・・・
 
動的辞書コード:
/*
MiYuオリジナル、転帖は明記してください:転載は_______白い家
          http://www.cnblog.com/MiYu
Author By : MiYu
Test      : 1
Program   : 1671
*/
#include
using namespace std;
typedef struct dict DIC;
int f = 0;
DIC *root = NULL;
struct dict {
       dict (){ n = 0; flag = false;memset ( child , 0 , sizeof ( child ) ); }
       ~dict () { del ( root ); }
       static void insert ( char *ins )
       {
            DIC *cur = root,*now;
            int len = strlen ( ins );
            if ( len == 0 )  return ;
            for ( int i = 0; i != len;++ i )
            {
                  if ( cur->flag || ( i == len - 1 && cur->child[ ins[i] - '0' ] != NULL ) )
                       f = 1;
                  if ( cur->child[ ins[i] - '0' ] != NULL ) 
                  {
                       cur = cur->child[ ins[i] - '0' ];
                       cur->n++; 
                  }
                  else
                  {
                       now = new DIC;
                       cur->child[ ins[i] - '0' ] = now;
                       now->n++;
                       cur = now;
                  }
            } 
            cur->flag = true;
       }
       void del ( DIC * node )
       {
            if ( node == NULL )
                return;
            for ( int i = 0; i != 10;++ i )
            {
                 if ( node->child[i] != NULL )
                    del ( node->child[i] ); 
            } 
            free ( node );
       }
private:
       DIC *child[10];
       int n; 
       bool flag;
};
char num[11];
int main ()
{
    int T,N;
    scanf ( "%d",&T );
    while ( T -- )
    {
          DIC dict;
          root = &dict;
          f = 0;
          scanf ( "%d",&N );
          for ( int i = 0; i != N;++ i )
          {
                 scanf ( "%s",num );  
                 if ( f == 0 ) dict.insert ( num );            
          }
          puts ( f ? "NO": "YES"); 
    } 
    return 0;
}
 
STLコード:
/*
MiYuオリジナル、転帖は明記してください:転載は_______白い家
          http://www.cnblog.com/MiYu
Author By : MiYu
Test      :
Program   :
*/
#include
#include
#include
#include
using namespace std;
char num[11];
bool cmp ( const string &a, const string &b )
{
     return strcmp ( a.c_str(), b.c_str() ) < 0; 
}
int main ()
{
    int T,N;
    scanf ( "%d",&T );
    while ( T -- )
    {
          int f = 0;
          scanf ( "%d",&N );
          vector < string > vec;
          for ( int i = 0; i != N;++ i )
          {
                 scanf ( "%s",num );  
                 vec.push_back ( string ( num ) );           
          }
          sort ( vec.begin(), vec.end(),cmp1 );
          for ( int i = 1; i < N;++ i )
          {
                if ( vec[i].find ( vec[i-1] ) == 0 )
                {
                     f = 1; 
                     break;
                }
          }
          puts ( f ? "NO": "YES"); 
    } 
    return 0;
}
 
AMB大牛の静的コード:
 
#include
#include
using namespace std;
const int MAXNODE=500000;
const int BRANCH=10;

int Tree[MAXNODE][BRANCH],SIZE;
bool Key[MAXNODE];
bool Insert(char *str) {
    int Node=0;bool tof=false;
    for (int i=0;str[i];i++){
        int c=str[i]-'0';
        if(Tree[Node][c]==-1){
            Tree[Node][c]=++SIZE;tof=true;
            memset(Tree[SIZE],-1,sizeof(Tree[SIZE]));
        }
        if(Key[Node]) return false;
        Node=Tree[Node][c];
    }
    Key[Node]=true;
    return tof;
}

void Trie(){
    memset(Tree[0],-1,sizeof(Tree[0]));
    SIZE=0;
}

char str[15];
int main()
{
    int t,n;bool tof;
    scanf("%d",&t);
    while(t--){
        memset(Key,false,sizeof(Key));
        Trie();tof=true;
        scanf("%d",&n);
        for(int i=0;i
            scanf("%s",str);
            if(tof){
                tof=Insert(str);
            }
        }
        if(tof) puts("YES");
        else puts("NO");
    }
}