(哈希 树)51NOD 1095 Anigram单词

一个单词a如果通过交换单词中字母的顺序可以得到另外的单词b,那么定义b是a的Anigram,例如单词army和mary互为Anigram。另:相同的2个单词不算Anigram。现在给定一个字典,输入Q个单词,从给出的字典中找出这些单词的Anigram。

 

输入

第1行:1个数N,表示字典中单词的数量。(1 <= N <= 10000)
第2 - N + 1行,字典中的单词,单词长度 <= 10。
第N + 2行:查询的数量Q。(1 <= Q <= 10000)
第N + 3 - N + Q - 2行:用作查询的单词,单词长度 <= 10。

输出

共Q行,输出Anigram的数量,如果没有输出0。

输入样例

5
add
dad
bad
cad
did
3
add
cac
dda

输出样例

1
0
2

解:通过哈希求相同字母的单词数量,通过树状结构求相同单词,两者之差即可。
 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <malloc.h>
 4 
 5 long long key[10000], ans[10000];
 6 int pri[26] = { 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101 };
 7 char cap = 'a';
 8 
 9 typedef struct Tree
10 {
11     char alp,end;
12     struct Tree* bro,* son;
13 }tree;
14 
15 int main()
16 {
17     int n;
18     while (scanf_s("%d", &n) != EOF)
19     {
20         char word[11];
21         tree* dict = NULL;
22         for (int i = 0; i < n; ++i)
23         {
24             scanf_s("%s", word, 11);
25             int j = 0, len = strlen(word);
26             key[i] = 1;
27             if (word[0] < 'a') cap = 'A';
28             for (tree** p = &dict, *ps = dict; j < len; ++j)
29             {
30                 key[i] *= pri[word[j] - cap];
31                 if (ps == NULL)
32                 {
33                     loop1:ps = malloc(sizeof(tree));
34                     ps->alp = word[j];
35                     ps->bro = ps->son = NULL;
36                     *p = ps;
37                     ps->end = 0;
38                 }
39                 else
40                 {
41                     while (ps->alp != word[j])
42                     {
43                         p = &(ps->bro);
44                         ps = ps->bro;
45                         if (ps == NULL) goto loop1;
46                     }
47                 }
48                 if (j == len - 1) ps->end = 1;
49                 p = &(ps->son);
50                 ps = ps->son;
51             }
52         }
53         int q;
54         scanf_s("%d", &q);
55         for (int i = 0; i < q; ++i)
56         {
57             scanf_s("%s", word, 11);
58             int j = 0, len = strlen(word), s = -1;
59             ans[i] = 1;        
60             for (tree* p = dict; j < len; ++j)
61             {
62                 ans[i] *= pri[word[j] - cap];
63                 if (s == 0) continue;
64                 while (p->alp != word[j])
65                 {
66                     p = p->bro;
67                     if (p == NULL)
68                     {
69                         s = 0;
70                         break;
71                     }
72                 }
73                 if (j != len - 1 && p == NULL) s = 0;
74                 else if (j == len - 1)
75                 {
76                     if (p != NULL && p->end == 0)
77                         s = 0;
78                 }
79                 else if (p->son == NULL) s = 0;
80                 else p = p->son;
81             }
82             for (j = 0; j < n; ++j)
83             {
84                 if (key[j] == ans[i]) ++s;
85             }
86             printf("%d\n", s);
87         }
88     }
89     return 0;
90 }

 

posted @ 2019-09-03 20:34  Ekalos  阅读(239)  评论(0编辑  收藏  举报