整數區間(貪心)
阿新 • • 發佈:2019-01-24
請程式設計完成以下任務:
1.從檔案中讀取閉區間的個數及它們的描述;
2.找到一個含元素個數最少的集合,使得對於每一個區間,都至少有一個整數屬於該集合,輸出該集合的元素個數。
【輸入】
首行包括區間的數目n,1<=n<=10000,接下來的n行,每行包括兩個整數a,b,被一空格隔開,0<=a<=b<=10000,它們是某一個區間的開始值和結束值。
【輸出】
第一行集合元素的個數,對於每一個區間都至少有一個整數屬於該區間,且集合所包含元素數目最少。
【樣例輸入】
4
3 6
2 4
0 2
4 7
【樣例輸出】
2
【演算法分析】
•演算法模型:給n個閉區間[ai,bi], 在數軸上選儘量少的點,使每個區間內至少有一個點。
•演算法:首先按b1<=b2<=...<=bn排序。每次標記當前區間的右端點x,並右移當前區間指標,直到當前區間不包含x,再重複上述操作。
•如下圖,如果選灰色點,移動到黑色點更優。
通俗的想,把區間想成一塊塊木板,把要找的點想成釘子,如果你的釘子很靠前的話,後面的木板就可能釘不到,每次把釘子釘在你要釘的木板最後,
這樣它就能順便釘更多木板啦
下面程式碼的看點有 多關鍵字快排
程式碼如下#include <cstdio> #include <cstring> #include <algorithm> using namespace std; int a[10002],b[10002],n; void qsort(int l,int r) { int i,j,m1,m2,p; i=l;j=r; m1=a[(l+r)/2];m2=b[(l+r)/2]; while(i<=j) { while(b[i]<m2||b[i]==m2&&a[i]<m1) ++i; while(b[j]>m2||b[j]==m2&&a[j]>m1) --j; if(i<=j) { p=a[i];a[i]=a[j];a[j]=p; p=b[i];b[i]=b[j];b[j]=p; ++i;--j; } } if(i<r) qsort(i,r); if(l<j) qsort(l,j); } int main() { //freopen("a.in","r",stdin); //freopen("a.out","w",stdout); scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d%d",&a[i],&b[i]); qsort(1,n); int x=-1,sum=0; for(int i=1;i<=n;++i) { if(x>=a[i]) continue; ++sum; x=b[i]; } printf("%d",sum); //fclose(stdin);fclose(stdout); }