[PO Final 2024] 鬼抓人 / Tag 题解

题目大意:

\(N\) 个人,有一个人是“猎人”,只有“猎人”碰到别人时,会把“猎人”的标记传递给对方,类似于烫手山芋。

\(M\) 次操作,每次操作为玩家 a 碰到 b。

现在你要求出有哪些人不是猎人也把猎人标记强制传递给对方,即触碰另一个玩家。

思路:

开两个 map,分别记录每个人是否存在猎人标记、每个人是否作弊。如果发现有人作弊,即不存在猎人标记就触碰对方,就标记此玩家为作弊。

代码中使用 vector 存储了作弊玩家,所以第二个 map 仅用来避免重复判断作弊者。

为什么我的语气这么像 AI 啊。

AC code:

#include<bits/stdc++.h>
using namespace std;
unordered_map<string,bool> mp,mp2;
vector<string> cheat;
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		string t;
		cin>>t;
		if(i==1) mp[t]=1;//初始时一号玩家为猎人。
	}
	int ans=0;
	while(m--){
		string x,t,y;
		cin>>x>>t>>y;
		if(!mp[x]&&!mp2[x]){//mp2用来避免重复判断作弊者。
			cheat.push_back(x);
			mp2[x]=1;
		}
		mp[y]=1,mp[x]=0; //无论该玩家是否作弊,都要将猎人标记传递下去。
	}
	sort(cheat.begin(),cheat.end());//注意按字典序排序!!!
	cout<<cheat.size()<<"\n";
	for(int i=0;i<cheat.size();i++) cout<<cheat[i]<<" ";
    return 0;
}
posted @ 2025-09-01 21:02  Frums  阅读(37)  评论(2)    收藏  举报