1. 程式人生 > >HihoCoder - 1672 區間問題(貪心)

HihoCoder - 1672 區間問題(貪心)

給定N個區間[Ai, Bi],請你找到包含元素最少的整數集合S,使得每個區間都至少有兩個整數在S中。  

例如給定三個區間[1, 3], [1, 4], [2, 5],則S={2, 3}。

Input

第一行包含一個整數N。

以下N行每行包含兩個整數Ai, Bi。  

對於30%的資料,1 ≤ N ≤ 1000  

對於100%的資料, 1 ≤ N ≤ 100000 1 ≤ Ai < Bi ≤ 1000000

Output

輸出一個整數代表S的大小。

Sample Input

3  
1 3 
1 4  
2 5  

Sample Output

2

 

解題思路:注意本題要求的時整數集合的大小即zhen整數集合最少有多少個元素,而不是求一個qu'j區間長度。

我們可以採用貪心策略,對所有區間按右端點進行排序,儘可能的更新一個區間使其包含更多的區間的其中兩個元素,如果當前要判斷的區間不能被包含兩個元素,我們就可以直接sum+2,捨棄一個區間取更靠右的區間(還是為了包含更多)。

設定兩個變數l,r不斷更新左右邊界,這裡有三種情況:

1.當前判斷的區間在[l,r]的左邊。該區間中沒有元素在[l,r]裡,sum+2,更新r,l

2.當前判斷的區間左端點在[l,r]的左邊而右端點在[l,r]中間(即是相交了),該區間有至少一個元素在[l,r]中,sum+1,更新r,l

3.當前判斷的區間的右端點在[l,r]的右邊,該區間已有兩個元素在[l,r]裡,不需要更新

 

AC程式碼:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
using namespace std;

struct node
{
	int a,b;
} qu[100010];

bool cmp(node x,node y)
{
	if(x.b==y.b) return x.a>y.a;
	return x.b<y.b;
}

int main()
{
	int n;
	while(~scanf("%d",&n))
	{
		for(int i=0;i<n;i++)
		{
			scanf("%d%d",&qu[i].a,&qu[i].b);
		}
	
		sort(qu,qu+n,cmp);
	
		int sum=0,l=0,r=0;
		for(int i=0;i<n;i++)
		{
			if(l>=qu[i].a) continue;
			else if(r>=qu[i].a)
			{
				sum++;
				l=r;
				r=qu[i].b;
			}
			else
			{
				sum+=2;
				r=qu[i].b;
				l=r-1;
			}
		}
		printf("%d\n",sum);
	}
	return 0;
}