题意:原题在这
给出整数n(n<=10000)表示人数。接下来 n 行,每行一个字符串表示人名(互不相同,且只含小写字母,长度不超过 50)。第 n+2 行一个整数 m,表示教练报的名字。接下来 m 行,每行一个字符串表示教练报的名字(只含小写字母,且长度不超过 50)。判断教练报的名字是否错误或重复
做法:(详见行内注释)
简单模板题
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; int n,m; int tot=0;//节点总数 struct node { bool have; int cnt; int son[27]; node() { cnt=0; memset(son,false,sizeof son); have=false; } }tree[800005]; void insert(string c)//插入字符串s { int now=0; for(int i=0;i<c.size();i++) { int v=c[i]-'a'; if(tree[now].son[v]==0)//结点不存在 { tree[now].son[v]=++tot;//新建结点 } now=tree[now].son[v]; // tree[now].cnt++;//统计出现次数 } tree[now].have=1; } int find(string c) { int now=0; for(int i=0;i<c.size();i++) { int v=c[i]-'a'; if(!tree[now].son[v]) return 3; now=tree[now].son[v]; } if(!tree[now].have) return 3; if(!tree[now].cnt) { tree[now].cnt++; return 1; } return 2; } int main() { char name[100],point[100]; scanf("%d",&n); for (int i=1;i<=n;++i) { cin>>name; insert(name); } scanf("%d",&m); for (int i=1;i<=m;++i) { cin>>point; int p=find(point); if (p==1) cout<<"OK"<<endl; else if(p==2) cout<<"REPEAT"<<endl; else if(p==3) cout<<"WRONG"<<endl; } return 0; }
附一个普通Trie模板:
//O(26*s.size()); int tot=0;//节点总数 string s; struct node { int cnt; // vector<int> son;//省空间 int son[27];//省时间 //STL map较为均衡 }tree[100005]; void insert(string c)//插入字符串s { int now=1; for(int i=1;i<=c.size();i++) { int v=c[i]-'a'; if(tree[now].son[v]==0)//结点不存在 { tree[now].son[v]=++tot;//新建结点 } now=tree[now].son[v]; tree[now].cnt++;//统计出现次数 } } bool find(string c)//c串存不存在 { int now=1; for(int i=1;i<=c.size();i++) { int v=c[i]-'a'; if(!tree[now].cnt) return true; else return false; } }