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

于是他错误的点名开始了

题目背景

XS中学化学竞赛组教练是一个酷爱炉石的人。

他会一边搓炉石一边点名以至于有一天他连续点到了某个同学两次,然后正好被路过的校长发现了然后就是一顿欧拉欧拉欧拉(详情请见已结束比赛 CON900)。

题目描述

这之后校长任命你为特派探员,每天记录他的点名。校长会提供化学竞赛学生的人数和名单,而你需要告诉校长他有没有点错名。(为什么不直接不让他玩炉石。)

输入格式

第一行一个整数 \(n\),表示班上人数。

接下来 \(n\) 行,每行一个字符串表示其名字(互不相同,且只含小写字母,长度不超过 \(50\))。

\(n+2\) 行一个整数 \(m\),表示教练报的名字个数。

接下来 \(m\) 行,每行一个字符串表示教练报的名字(只含小写字母,且长度不超过 \(50\))。

输出格式

对于每个教练报的名字,输出一行。

如果该名字正确且是第一次出现,输出 OK,如果该名字错误,输出 WRONG,如果该名字正确但不是第一次出现,输出 REPEAT

样例 #1

样例输入 #1

5  
a
b
c
ad
acd
3
a
a
e

样例输出 #1

OK
REPEAT
WRONG

提示

  • 对于 \(40\%\) 的数据,\(n\le 1000\)\(m\le 2000\)
  • 对于 \(70\%\) 的数据,\(n\le 10^4\)\(m\le 2\times 10^4\)
  • 对于 \(100\%\) 的数据,\(n\le 10^4\)\(m≤10^5\)

本题可以直接用stl大法

using namespace std;
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
	int n,m;
	cin>>n;
	map<string,int>mp;
	map<string,int>mp2;
	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;
		mp2[s]++;
		if(mp[s]&&mp2[s]>=2){
			cout<<"REPEAT\n";
		}else if(mp[s]&&mp2[s]==1){
			cout<<"OK\n";
		}else{
			cout<<"WRONG\n";
		}
	}
	return 0;
} 

当然本题训练的是字典树

using namespace std;
const int N=1e5+10;
map<string,int>mp;
int tr[N][26];
int vis[N][26];
int cnt=1;
void insert(string s){
	int cur=1;
	for(auto c:s){
		if(!tr[cur][c-'a'])tr[cur][c-'a']=++cnt;
		cur=tr[cur][c-'a'];
	}
	vis[cur][s[s.size()-1]-'a']=1;
}
bool find(string s){
	int cur=1;
	for(auto c:s){
		if(!tr[cur][c-'a'])return false;
		cur=tr[cur][c-'a'];
	}
	if(vis[cur][s[s.size()-1]-'a']){
		return true;
	}else return false;
}
int main(){
	int n,m;
	cin>>n;
	for(int i=1;i<=n;i++){
		string s;
		cin>>s;
		insert(s);
	}
	cin>>m;
	for(int i=1;i<=m;i++){
		string s;
		cin>>s;
		mp[s]++;
		if(find(s)&&mp[s]==1){
			cout<<"OK\n";
		}else if(find(s)&&mp[s]>1){
			cout<<"REPEAT\n";
		}else{
			cout<<"WRONG\n";
		}
	}
	return 0;
} 
posted @ 2023-11-24 13:12  yufan1102  阅读(15)  评论(0)    收藏  举报