Codeforces 861D - Polycarp's phone book 【Trie树】

<题目链接>

题目大意:

 输入7e4个长度为9的字符串,每个字符串中只出现0~9这几种数字,现在需要你输出每个母串中最短的特有子串。

解题分析:

 利用Trie树进行公共子串的判定,因为Trie树的特性是对节点的前缀字符串进行操作,所以为了转换成对母串中任意区间的字符串进行操作,我们对母串中的所有后缀字符串建树。下面用了一个比较优秀的Trie树模板。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int N = 7e4+10;
 8 const int INF = 1e6;
 9 char buf[N][11];
10 int n,cur;
11 struct Trie{
12     int nxt[N*11][12],num[N*11],time[N*11];     
13     int root,pos;
14     int newnode(){
15         for(int i=0;i<10;i++)nxt[pos][i]=-1;
16         num[pos]=0,time[pos]=0;
17         return pos++;
18     }
19     void init(){
20         pos=0;root=newnode();
21     }
22     void insert(char str[]){
23         int len=strlen(str);
24         int now=root;
25         for(int i=0;i<len;i++){
26             int to=str[i]-'0';
27             if(nxt[now][to]==-1)
28                 nxt[now][to]=newnode();
29             now=nxt[now][to];
30             if(time[now]!=cur)     //建立时间戳的意义是,避免相同母串中不同位置中的相同子串产生重复标记
31                 num[now]++,time[now]=cur;      //num[now]记录下含有这个子串的母串数量
32         }
33     }
34     int query(char str[]){
35         int len=strlen(str);
36         int now=root;
37         for(int i=0;i<len;i++){
38             now=nxt[now][str[i]-'0'];
39             if(num[now]==1)return i;
40         }
41         return -1;
42     }
43 }trie;
44 
45 int main(){
46     ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
47     cin>>n;
48     trie.init();
49     for(int i=1;i<=n;i++){
50         cin>>buf[i];
51         cur=i;
52         for(int j=0;j<10;j++){
53             trie.insert(buf[i]+j);     //用每个母串的所有后缀建Trie树,然后利用Trie树对前缀字符串进行操作的特性,达到对母串字符区间的操作
54         }
55     }
56     for(int i=1;i<=n;i++){
57         int le=0,ri=0,mn=INF;
58         for(int j=0;j<10;j++){
59             int tmp=trie.query(buf[i]+j);
60             if(tmp!=-1 && mn>tmp){      //找到每个母串中符合条件的最短子串
61                 mn=tmp;le=j,ri=j+tmp;
62             }
63         }
64         for(int j=le;j<=ri;j++)cout<<buf[i][j];
65         puts("");
66     }
67 }

2019-02-01

猜你喜欢

转载自www.cnblogs.com/00isok/p/10347200.html