题目链接 : CODEFROCE 420B
题目分析:
一道挺有挑战性的题。告诉你有N个人,而现在要从中判断哪些人有可能是领导。是领导的条件是,在有人在的时候他必须在,没人的时候可有可无。现在给出了M条记录,叫你来判断哪些人有可能是领导。
思路解析:
我们可以用模拟的思路把这个过程给算出来。因为,在M条记录中没出现的人肯定是有可能是领导的。所以,我们只要判断给出的M条记录中的人就好了。
#include <cstdio>
#include <set>
using namespace std;
bool type[100005];
int ind[100005];
set<int> haveInBeg;
int main(){
int n, m;
scanf("%d%d", &n, &m);
for(int i=0; i < m; ++i){
char inp[2];
scanf("%s%d", inp, ind+i);
--ind[i];
if(inp[0] == '+'){
type[i]=1;
}
else{
type[i]=0;
}
}
for(int i=m-1; i >= 0; --i){ //保存先出现退出记录的人(因为我们可以假设他是很早很早出现的)
if(type[i]){
haveInBeg.erase(ind[i]);
}
else{
haveInBeg.insert(ind[i]);
}
}
set<int> ans;
for(int i=0; i < n; ++i)
ans.insert(i);
for(int i=0; i < m; ++i){
if(type[i]){
if(i && ind[i-1] != ind[i]) //前面有人,但是ind[i]不在
ans.erase(ind[i]);
if(!haveInBeg.empty()) //前面有人,ind[i]不在
ans.erase(ind[i]);
haveInBeg.insert(ind[i]); //模拟,让他进入
}
else{
if(i < m-1 && ind[i+1] != ind[i]) //他不是最后一个离场
ans.erase(ind[i]);
haveInBeg.erase(ind[i]); //模拟,让他离开
if(!haveInBeg.empty()) //还有人没离开,而他先离开了
ans.erase(ind[i]);
}
}
printf("%d\n", ans.size());
for(auto it = ans.begin(); it != ans.end(); ++it)
printf("%d ", *it+1);
}