版权声明:本文为博主原创文章,顺手点个赞叭~有问题欢迎指出(*╹▽╹*) https://blog.csdn.net/qq_41117236/article/details/89502378
【题面】
【题解】
题意:给定一些区间,按升序输出删除最少的区间的序号使得剩下的区间没有任意三个区间两两相交。
思路:用贪心的思想,首先将区间按左端点升序排序,左端点相同则按右端点升序排序,然后判断三个区间是否两两相交,如果两两相交,则删除右端点最大的那个区间,因为右端点越大对后续区间的影响越大;如果不相交,则更新右端点最大的两个区间跟后续区间进行比较。
【代码】
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
vector <int> vec;
struct p{
ll l,r;
int num;
}f[50005],ff[5];
bool cmp(p a,p b)
{
if(a.l==b.l)
return a.r<b.r;
return a.l<b.l;
}
bool cmpp(p a,p b)
{
return a.r<b.r;
}
bool check(p x,p y,p z)
{
return y.l<=x.r&&z.l<=x.r&&z.l<=y.r;
}
int main()
{
int t; scanf("%d",&t);
while(t--){
vec.clear();
int n; scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%lld%lld",&f[i].l,&f[i].r);
f[i].num=i+1;
}
sort(f,f+n,cmp);
ff[0]=f[0],ff[1]=f[1];
for(int i=2;i<n;i++){
ff[2]=f[i];
sort(ff,ff+3,cmp);
if(check(ff[0],ff[1],ff[2])){
sort(ff,ff+3,cmpp);
vec.push_back(ff[2].num);
}
else{
sort(ff,ff+3,cmpp);
ff[0]=ff[2];
}
}
sort(vec.begin(),vec.end());
printf("%d\n",vec.size());
for(int i=0;i<vec.size();i++)
printf(i<vec.size()-1?"%d ":"%d\n",vec[i]);
}
return 0;
}