P2580 于是他错误的点名开始了 字典树

题意:给出n个模式串,给出m个查询串

     问每一个查询串是否出现过?如果没出现过,就打印WRONG

   如果出现过,则看起被查询了几次,如果到目前为止(包括本次)查询过一次,则输出OK

                                多次则输出 REPEAT

思路:直接建字典树

   跑查询的时候,如果找不到,就返回0

    如果已经找到,则用vis数组来标记到目前为止这个串被查询了多少次

      然后返回按对应结果输出

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=5e5+10;  //大小开模式串个数*模式串长度
 4 char s[100];
 5 int vis[maxn];
 6 int trie[maxn][26];
 7 int tot;
 8 void Insert()
 9 {
10     int rt=0;
11     for(int i=0;i<strlen(s);i++){
12         int id=s[i]-'a';
13         if(!trie[rt][id]) trie[rt][id]=++tot;
14         rt=trie[rt][id];
15     }
16 }
17 int Search()
18 {
19     int rt=0;
20     for(int i=0;i<strlen(s);i++){
21         int id=s[i]-'a';
22         if(!trie[rt][id]) return 0;
23         rt=trie[rt][id];
24     }  //rt经过此循环后变成前缀最后一个字母所在位置
25     vis[rt]++;
26     return vis[rt]; //返回当前字符串结尾节点的访问次数,也就是作为前缀的出现次数
27 }
28 int main()
29 {
30     int n;
31     scanf("%d",&n);
32     for(int i=1;i<=n;i++){
33         scanf("%s",s);
34         Insert();
35     }
36     int m;
37     scanf("%d",&m);
38     while(m--){
39         scanf("%s",s);
40         int tmp=Search();
41         if(!tmp) printf("WRONG\n");
42         else if(tmp==1) printf("OK\n");
43         else printf("REPEAT\n");
44     }
45     return 0;
46 }
View Code

 

posted @ 2020-04-07 11:02  古比  阅读(107)  评论(0编辑  收藏  举报