一道用STL的貪心,正好能夠用來學習使用STL庫c++
題目大意:給出n條能夠內含,相交,分離的線段,若是重疊條數超過k次則爲壞點,n,k<2e5學習
因此咱們貪心的想咱們從左往右遍歷,若是重合部分條數超過了k,就必須去除線段,(此時從左邊看去除線段後不會出現衝突,右邊還有剩餘不少線段未知)因此咱們選擇去除這些重合線段裏右端最右的部分spa
實現:3d
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int maxn =2e5+30;
set<pii>res;
vector<pii>v[maxn];
vector<int>ans;
int main(){
int n,k,mx=0,t1,t2;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%d%d",&t1,&t2);
v[t1].push_back({t2,i});//左端點t1儲存右端點和序號i,C11的用法這裏{t2,i}等於make_pair
mx=max(t2,mx);
}
for(int i=0;i<=mx;i++){
while(res.begin()->first <i&&!res.empty())//當右端點小於i時已經徹底掃過,此時刪去該線段
res.erase(res.begin());//刪去整條線段
for(int j=0;j<v[i].size();j++)
res.insert(v[i][j]);//插入該端點爲左端點下的線段
while(res.size()>k){//若是此時重合部分大於k,則找到這些線段裏右端點最右的線段,加入ans並刪去
ans.push_back(res.rbegin()->second);//rbegin()返回的是最末元素的位置
res.erase(--res.end());//注意雖然效果同樣但end和rbegin的類型不同
}
}
cout<<ans.size()<<endl;
for(auto x:ans){
cout<<x<<' ';
}
cout<<endl;
}code
原題連接:https://codeforces.com/contest/1249/problem/D2blog
關於迭代器的tipip