51NOD

来源:互联网 发布:java实现icmp 编辑:程序博客网 时间:2024/05/11 00:36

题目

有若干个活动,第i个开始时间和结束时间是[Si,fi),活动之间不能交叠,要把活动都安排完,至少需要几个教室?

输入

第一行一个正整数n (n <= 10000)代表活动的个数。
第二行到第(n + 1)行包含n个开始时间和结束时间。
开始时间严格小于结束时间,并且时间都是非负整数,小于1000000000

输出

一行包含一个整数表示最少教室的个数。

输入示例

3
1 2
3 4
2 9

输出示例

2
题意: 略

分析: 和之一不同,这次求得是教室,上个求得是活动,很容易就可以想到,我们这次是按照左端点排序,然后贪心让每个教室放更多的活动,这里我用了个vis数组,来记录下每个活动的状态,剩下的就是暴力了。
参考了一位大牛的思路:把线段转化成一个入点和一点出点,这样存下2*n个点,之后按坐标从小到大给这2*n个点排序,之后O(n)遍历一遍就好,遇到入点sum++, 遇到出点sum–,遍历时最大的sum便是答案。Orz..

参考代码

#include <bits/stdc++.h>using namespace std;struct s {    int l,r;}a[10010];bool vis[10010];bool cmp(s x, s y) {    if(x.l == y.l) return x.r < y.r;    return x.l < y.l;}int main() {    ios_base::sync_with_stdio(false);    int n;cin>>n;    for(int i = 0;i < n;i++) {        cin>>a[i].l>>a[i].r;    }    sort(a,a+n,cmp);    int res = 0;    while (true) {        bool flg = false;        int R;        for(int i = 0;i < n;i++) {            if(!flg && !vis[i]) {                R = a[i].r;                flg = true;                vis[i] = true;                continue;            }            if(!vis[i] && a[i].l >= R) {                R = a[i].r;                vis[i] = true;            }        }        if(flg) res++;        else break;    }    cout<<res<<endl;    return 0;}

思维代码

#include <bits/stdc++.h>using namespace std;vector<pair<int,bool> > a;int main() {    int n;cin>>n;    int l,r;    for(int i = 0;i < n;i++) {        cin>>l>>r;        a.push_back(make_pair(l,true));        a.push_back(make_pair(r,false));    }    sort(a.begin(),a.end());    int sum = 0,t = 0;    for(int i = 0;i < 2*n;i++) {        if(a[i].second) t++;        else t--;        sum = max(sum,t);    }    cout<<sum<<endl;    return 0;}
  • 如有错误或遗漏,请私聊下UP,thx