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; }