HDU-1671 Phone List暴力版+辞書ツリー

20374 ワード

この問題は、与えられた列セットにいくつかの列があるかどうかを判定することが、他の列の接頭辞列であるという問題である.ディクショナリツリーでは、1つの列を構築するパスにすでにあるノードがマークされているかどうか(ここに列の終わりがある)と、1つの列がそこにある場合、その子供が空であるかどうかを判定するだけで便利です.
ここでは、与えられたすべての数字をlong long型で格納し、小さい順に並べ替えた後、1文字列とその順番に末位を除いたサブストリングがすでに存在するかどうかを判定し、存在する場合はNOを出力し、そうでない場合はYESを出力する暴力版が書かれている.ここでは、いくつかの処理をしなければWAになることがあります.それは、各配列の前に1を加えることで、列の先頭ゼロを意味させます.
コードは次のとおりです.
 1 #include <cstring>
2 #include <cstdlib>
3 #include <cstdio>
4 #include <map>
5 using namespace std;
6
7 long long rec[10005];
8
9 void getstr( char *s )
10 {
11 char c;
12 int cnt = 1;
13 while( c = getchar(), c < '0' || c > '9' ) ;
14 s[cnt++] = c;
15 while( c = getchar(), c != '
' )
16 s[cnt++] = c;
17 s[cnt] = '\0';
18 }
19
20 void getlonglong( long long &x )
21 {
22 x = 1; // 1
23 char c;
24 while( c = getchar(), c < '0' || c > '9' ) ;
25 x = x * 10 + c - '0';
26 while( c = getchar(), c >= '0' && c <= '9' )
27 x = x * 10 + c - '0';
28 }
29
30 int cmp( const void *a, const void *b )
31 {
32 return *( long long * )a - *( long long * )b;
33 }
34
35 int main()
36 {
37 int T;
38 scanf( "%d", &T );
39 while( T-- )
40 {
41 map<long long, bool>mp;
42 int N, flag = 0;
43 scanf( "%d", &N );
44 for( int i = 0; i < N; ++i )
45 {
46 getlonglong( rec[i] );
47 }
48 qsort( rec, N, sizeof( rec[0] ), cmp );
49 for( int i = 0; i < N; ++i )
50 {
51 long long x = rec[i];
52 if( mp.count( x ) == 0 )
53 mp[x] = true;
54 else
55 {
56 flag = 1;
57 break;
58 }
59 x /= 10;
60 while( x > 1 && !flag )
61 {
62 if( mp.count( x ) == 0 )
63 {
64 x /= 10;
65 }
66 else
67 {
68 flag = 1;
69 break;
70 }
71 }
72 }
73 printf( flag ? "NO
" : "YES
" );
74 }
75 return 0;
76 }