2019上海icpc区域赛补题
Posted xiaobuxie
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2019上海icpc区域赛补题相关的知识,希望对你有一定的参考价值。
B:
问题简述:给你n个长度最多为10 的 数字字符串,问是否存在某个字符串是另一个字符串的前缀。
所需知识点:字典树
问题形式化描述:使用某个数据结构,统计所有字符串,并且支持快速查询统计的字符串当中是否存在字符串是当前查询串的前缀。
解题思路:对所欲给定的n个字符串建立一颗字典树,并且对 每个字符串的末尾节点 的值加一,即每一个节点维护有多少个字符串以当前节点为结尾。对每一个字符串,我们在字典树上遍历,假如当前字符串遍历的节点(除了末节点)当中存在值不是0的节点,或者末尾节点的值大于1, 则存在,否则则不存在。
参考代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N = 1e4+9; 4 string a[N]; 5 struct Node{ 6 int v; 7 int son[11]; 8 }tr[N*10]; 9 int tot; 10 void ins(string s){ 11 int n = s.size(); 12 int now = 1; 13 for(int i = 0;i<n;++i){ 14 int w = s[i] - ‘0‘; 15 if(tr[now].son[w] == 0) tr[now].son[w] = ++tot; 16 now = tr[now].son[w]; 17 } 18 tr[now].v++; 19 } 20 bool que(string s){ 21 int n = s.size(); 22 int now = 1; 23 for(int i = 0;i<n-1;++i){ 24 int w = s[i] - ‘0‘; 25 now = tr[now].son[w]; 26 if(tr[now].v) return 0; 27 } 28 now = tr[now].son[s[n-1]-‘0‘]; 29 if(tr[now].v>1) return 0; 30 return 1; 31 } 32 int main(){ 33 int T; cin>>T; 34 for(int cas = 1;cas<=T;++cas){ 35 tot = 1; 36 int n; cin>>n; 37 for(int i = 1;i<=n;++i) cin>>a[i]; 38 for(int i = 1;i<=n;++i) ins(a[i]); 39 bool ok = 1; 40 for(int i = 1;i<=n && ok;++i){ 41 if(!que(a[i])) ok = 0; 42 } 43 cout<<"Case #"<<cas<<": "<<(ok?"Yes":"No")<<endl; 44 for(int i = 1;i<=tot;++i){ 45 for(int j = 0;j<=9;++j) tr[i].son[j] = 0; 46 tr[i].v = 0; 47 } 48 } 49 return 0; 50 }
以上是关于2019上海icpc区域赛补题的主要内容,如果未能解决你的问题,请参考以下文章
第 46 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(上海),签到题6题