「一本通 1.1 练习 3」线段

题目传送门

解题思路

这题我们可以按右端点从小到大排序,我们选择第一条线段作为初始线段,然后判断下一条线段的左端点是否大于等于当前选中线段的右端点即可。

证明:排序后显然当你选了一个线段后,再要从后面选一个线段,其左端点必须>=你的右端点。右端点当然越小越好。

因为这题数据量过大,我们可以使用读入外挂来优化程序的运行时间。

#include <bits/stdc++.h>
#define _for(i,a,n) for(int i=a;i<n;++i)
#define rep(i,a,n)for(int i=a;i<=n;++i)
#define input() int T;cin>>T;while(T--)
#define close() ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
typedef long long ll;
template<class T>inline void read(T &x){bool Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;}
template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x%10+'0');}
template<class T>inline void writeln(T x){if(x<0)putchar('-');x=abs(x);print(x);putchar('\n');}
template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);}
using namespace std;
const int maxn = 1e6;

struct node {
    int l, r;
    inline bool operator < (const node & x) const {
        return r < x.r;
    }
}arr[maxn + 5];

int main()
{
    int n;
    read(n);
    _for(i, 0, n) read(arr[i].l), read(arr[i].r);
    sort(arr, arr + n);
    int ed = arr[0].r;
    int ans = 1;
    _for(i, 1, n) {
        if(arr[i].l >= ed) {
            ed = arr[i].r;
            ans++;
        }
    }
    cout << ans << endl;

    return 0;
}

posted @ 2018-12-25 09:58 schrodingercatss 阅读(...) 评论(...) 编辑 收藏