ZOJ - 3953 Intervals (贪心)

Intervals
Time Limit: 1 Second      Memory Limit: 65536 KB      Special Judge
Chiaki has n intervals and the i-th of them is [li, ri]. She wants to delete some intervals so that there does not exist three intervals a, b and c such that a intersects with b, b intersects with c and c intersects with a.

Chiaki is interested in the minimum number of intervals which need to be deleted.

Note that interval a intersects with interval b if there exists a real number x such that la ≤ x ≤ ra and lb ≤ x ≤ rb.

Input
There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

The first line contains an integer n (1 ≤ n ≤ 50000) -- the number of intervals.

Each of the following n lines contains two integers li and ri (1 ≤ li < ri ≤ 109) denoting the i-th interval. Note that for every 1 ≤ i < j ≤ n, li ≠ lj or ri ≠ rj.

It is guaranteed that the sum of all n does not exceed 500000.

Output
For each test case, output an integer m denoting the minimum number of deletions. Then in the next line, output m integers in increasing order denoting the index of the intervals to be deleted. If m equals to 0, you should output an empty line in the second line.

Sample Input
1
11
2 5
4 7
3 9
6 11
1 12
10 15
8 17
13 18
16 20
14 21
19 22
Sample Output
4
3 5 7 10

题意:

n个区间的左右端点,让你取走一些区间,使得任何三个区间都不两两相交。

思路:

贪心+排序,首先,根据区间的左端点排序,然后每三个判断是否相交,如果相交,走删除最靠右边的;不相交的话,留下两个最靠右边的

#include <bits/stdc++.h>

using namespace std;
const int N=50005;
struct node
{
    int l,r,id,len;
} a[N],b[4],c[4],d[4];
bool cmp(node x,node y)
{
    if(x.l==y.l)
        return x.r<y.r;

    return x.l<y.l;
}
bool cmp1(node x,node y)
{
    if(x.r==y.r)
        return x.l<y.l;

    return x.r<y.r;
}
vector<int> v;
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        v.clear();
        scanf("%d",&n);
        for(int i=1; i<=n; i++)
        {
            scanf("%d%d",&a[i].l,&a[i].r);
            a[i].id=i;
            a[i].len=a[i].r-a[i].l+1;
        }
        sort(a+1,a+n+1,cmp);
        int ans=0;
        b[1]=a[1];
        b[2]=a[2];
        node x,y,z;
        for(int i=3; i<=n; i++)
        {
            b[3]=a[i];
            sort(b+1,b+3+1,cmp1);
			x=b[1];
			y=b[2];
			z=b[3];
			
			if(x.r>=y.l&&z.l<=x.r&&z.r>=y.l)
            {      
                ans++;
                v.push_back(b[3].id);
            }
            else
            {
				b[1]=b[2];
				b[2]=b[3];
            }
            //cout<<v[ans-1]<<endl;
        }
        printf("%d\n",ans);
        if(ans!=0)
        {
        	sort(v.begin(),v.end());
            for(int i=0; i<ans-1; i++)
            {
                printf("%d ",v[i]);
            }
            printf("%d\n",v[ans-1]);
        }
        else
        	cout<<endl;
    }
    return 0;
}

 

#include <bits/stdc++.h>

using namespace std;
const int N=50005;
struct node
{
    int l,r,id,len;
} a[N];
bool cmp(node x,node y)
{
    if(x.l==y.l)
        return x.r<y.r;

    return x.l<y.l;
}
vector<int> v;
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        v.clear();
        scanf("%d",&n);
        for(int i=1; i<=n; i++)
        {
            scanf("%d%d",&a[i].l,&a[i].r);
            a[i].id=i;
            a[i].len=a[i].r-a[i].l+1;
        }
        sort(a+1,a+n+1,cmp);
        int ans=0;
        
        node x=a[1],y=a[2],z;
       
        for(int i=3; i<=n; i++)
        {
            z=a[i];
            /* cout<<x.l<<" "<<x.r<<endl;
             cout<<y.l<<" "<<y.r<<endl;
             cout<<z.l<<" "<<z.r<<endl;
             cout<<endl;  */
            //if(x.r>y.l&&z.l<x.r&&z.r>y.l)
            if(x.l>y.l)
			{
				node t=x;
				x=y;
				y=t;
				
			}
            if(z.l<=y.r&&z.l<=x.r)
            {
                ans++;
                if(z.r>=y.r&&z.r>=x.r)
				{
					v.push_back(z.id);
				}
				else if(y.r>=z.r&&y.r>=x.r)
				{
					v.push_back(y.id);
					y=z;
				}
				else
				{
					v.push_back(x.id);
					x=y;
					y=z;
				}
            }
            else
            {
            	node t;
				if(z.r>=y.r&&z.r>=x.r)
				{
					 t=y;
					 y=z;
					if(x.r<t.r)
					  x=t;	
				}
				else if(y.r>=z.r&&y.r>=x.r)
				{
					if(z.r>x.r)
						x=z;
				}
				else
				{
					t=y;
					y=x;
					if(z.r>t.r)
					   x=z;
					else
					   x=t;
				}
            }
            //cout<<v[ans-1]<<endl;
        }
        printf("%d\n",ans);
        if(ans!=0)
        {
        	sort(v.begin(),v.end());
            for(int i=0; i<ans-1; i++)
            {
                printf("%d ",v[i]);
            }
            printf("%d\n",v[ans-1]);
        }
        else
        	cout<<endl;
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值