P2580 于是他错误的点名开始了 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
字典树写法:
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define lint long long
int n,m;
struct Trie{
int ch[500010][26],cnt,val[500010];
//val为附加信息
//ch数组,第二维的大小为26是因为字符串只由小写字母构成,第二维的大小一般是由字符串的组成决定
//cnt即为节点编号
Trie(){
cnt=1;//一开始的时候只有根节点这一个节点
memset(ch[0],0,sizeof(ch[0]));
memset(val,0,sizeof(val));
}
void insert(char *s,int v){
//s代表要插入的字符串,v为附加信息
int u=0,len=strlen(s+1);//u限制该节点的子节点
for(int i=1;i<=len;i++){
int c=s[i]-'a';
if(!ch[u][c]){//如果节点不存在就插入,不然就继续往下遍历
ch[u][c]=cnt++;//新建节点
}
u=ch[u][c];//往下遍历
}
val[u]=v;//插入附加信息,一般只在叶子节点插入附加信息,中间的节点一般是没有附加信息的
}
int find(char *s){
//查找这个字符串是否在Trie中出现过,如果出现过,返回它的附加信息
int u=0,len=strlen(s+1);
for(int i=1;i<=len;i++){
int c=s[i]-'a';
if(!ch[u][c]) return 0; //没有这个节点,返回0,即代表这个字符串没有在Trie中出现过
u=ch[u][c];//继续向下遍历
}
if(val[u]==0) {val[u]++; return 1;}
if(val[u]==1) return 2; //第二次返回2
}
} trie;
int main(){
cin >> n;
for(int i=1;i<=n;i++){
char s[100];
scanf("%s",s+1);
trie.insert(s,0);
}
cin >> m;
for(int i=1;i<=m;i++){
char s[100];
scanf("%s",s+1);
int f=trie.find(s);
if(f==1) {cout << "OK\n"; continue;}
if(!f) {cout << "WRONG\n"; continue;}
if(f==2) {cout << "REPEAT\n"; continue;}
}
return 0;
}
STL map写法:
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define lint long long
map<string,int> mp;
int n,m;
int main(){
cin >> n;
for(int i=1;i<=n;i++){
string s;
cin >> s;
mp[s]=1;
}
cin >>m;
for(int i=1;i<=m;i++){
string s;
cin >> s;
if(mp[s]==1){printf("OK\n");mp[s]++;continue;}
if(mp[s]==0){printf("WRONG\n");mp[s]++;continue;}
if(mp[s]>=1){printf("REPEAT\n");mp[s]++;continue;}
}
return 0;
}