ZOJ - 3953 Intervals (贪心)

版权声明:本文为蒟蒻原创文章,转载请注明出处哦~ https://blog.csdn.net/a54665sdgf/article/details/82912583

题目链接

题意:给你n个区间,让你从中去除尽可能少的区间,使得任意三个区间不两两相交。

解法:先对所有区间按照左端点值l从小到大排序,然后逐个放入一个长度为3的区间数组里。从第3个区间开始,如果三个区间发生了冲突,则删去右端点值r最大的区间,否则删去r最小的区间。

#define debug(a,n) for(int i=0;i<n;++i)cout<<a[i]<<' ';cout<<endl;
#define FRER() freopen("i.txt","r",stdin)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF=0x3f3f3f3f;
const int N=50000+10;
struct node
{
    int l,r,i;
    bool operator<(const node& b)const
    {
        return l!=b.l?l<b.l:r<b.r;
    }
} a[N];
bool cmp(const node& a,const node& b)
{
    return a.r>b.r;
}
int n;
node b[3];
vector<int> ans;

bool isinsect(const node& a,const node& b)
{
    if(a.r<b.l||b.r<a.l)return false;
    return true;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        ans.clear();
        scanf("%d",&n);
        for(int i=0; i<n; ++i)
        {
            scanf("%d%d",&a[i].l,&a[i].r);
            a[i].i=i;
        }
        sort(a,a+n);
        for(int i=0; i<2&&i<n; ++i)b[i]=a[i];
        for(int i=2; i<n; ++i)
        {
            b[2]=a[i];
            sort(b,b+3,cmp);
            if(isinsect(b[0],b[1])&&isinsect(b[1],b[2])&&isinsect(b[2],b[0]))
            {
                swap(b[2],b[0]);
                ans.push_back(b[2].i);
            }
        }
        sort(ans.begin(),ans.end());
        printf("%d\n",ans.size());
        for(int i=0; i<ans.size(); ++i)
        {
            if(i>0)printf(" ");
            printf("%d",ans[i]+1);
        }
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/a54665sdgf/article/details/82912583