stl中迭代器的删除
Z1584. noip题海战
Description
某校举行了k场集训,集训有两种方式:比赛和训练
对于每场比赛,他要保证所出的所有试题,对于所有学生来说,都是从来没有做过的
而对于每场训练,他要保证所出的所有题都被每一个参赛学生做过。
Format
Input
第一行2个正整数n和m,表示学生数和试题总数
第2~n+1行,先是1个正整数Q,接下来的Q个整数表示第i个学生的做题记录(可能重复做同一道题)
第n+2行,1个正整数k,表示要举行的比赛和训练总数
接下来的k行,每行的第一个正整数type表示是训练或比赛(1为训练,0为比赛)。
第2个数K表示参赛学生数,然后K个正整数表示参赛学生编号,每一行中的两个数之间有一个空格。
N<=100
M<=1000
K<=1000
Output
共k行,每行表示本次训练或比赛可选的题目(由小到大排序,中间用一个空格隔开,如果没有输出一个空行)。
Samples
输入数据 1
5 10
2 3 7
1 3
2 4 7
3 3 6 10
7 1 2 3 4 7 8 9
6
0 3 3 4 5
0 3 1 3 4
1 2 1 3
0 1 5
1 1 2
1 2 3 5
输出数据 1
5
1 2 5 8 9
7
5 6 10
3
4 7
Sol:
STL中迭代器的删除要非常小心,特别是在一边遍历一边删除的时候
例如要删除it这个迭代器
应该先把它的地址记下来....it2=it;
然后让it进行移动,it++
然后删除it2
另一个方法是
将要删除的迭代器地址记下来,放到一个迭代器数组中
当查找工作弄完了后,再一个个删除。
#include <bits/stdc++.h>
using namespace std;
const int N=1e3+10;
int n,m,x,k,num,type;
set<int>s[N],quanji,ans;
set<int>::iterator it,it2;
int main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>num;
for(int j=1;j<=num;j++)
{
cin>>x;//选手i做过的题号为x(题目必须去重)
s[i].insert(x);
}
}
for(int i=1;i<=m;i++)
quanji.insert(i);//预处理全集
cin>>k;
while(k--){
cin>>type>>num;
ans=quanji;//两个set之间可以用等于号赋值
if(type==0){//比赛,他要保证所出的题都没有被任何一个参赛学生做过
for(int i=1;i<=num;i++){
cin>>x;//选手编号为x
it=ans.begin();
while(it!=ans.end())
{
if(s[x].count(*it))
{
it2=it;
it++;
ans.erase(it2);//筛掉选手x做过的所有题
}
else
it++;
}
}
}
else{//训练,他要保证所出的题都被每一个参赛学生做过
for(int i=1;i<=num;i++){
cin>>x;//选手编号为x
for(it=ans.begin();it!=ans.end();){
if(!s[x].count(*it))ans.erase(it++);//筛掉选手x没做过的所有题
else it++;
}
}
}
for(it=ans.begin();it!=ans.end();it++)
printf("%d ",*it);
printf("\n");
}
return 0;
}

浙公网安备 33010602011771号