csu 1757(贪心或者树状数组)

1757: 火车入站

Time Limit: 1 Sec  Memory Limit: 128 MB
Submit: 209  Solved: 51
[Submit][Status][Web Board]

Description

火车站人们总是在站台等待列车进站,一个站台有火车停留的时候就不能有其他火车进入,今天有n辆火车经过,已知它们进站时间Si以及出站时间Ti,进站时间到出站时间之间火车必须有一个站台给它停靠,问让所有火车都能按时停靠,至少要安排多少个站台给这些火车

Input

第一行输入一个正整数T,表示数据组数
每组数据第一行输入一个正整数n,表示火车数量(n<=10000)
接下来n行,每行输入2个正整数Si,Ti,表示第i辆火车的进站时间和出站时间(Si<Ti<1e9)

Output

每组数据输出至少需要安排多少个站台

Sample Input

1
3
1 3
3 4
4 6

Sample Output

2


因为最多20000个点,树状数组的离散化一下,维护区间,最后求点的最大值.
#include <iostream>
#include <cstring>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
const int N = 100005;
int x[N],a[N],b[N];
int c[N],n;
int lowbit(int i){
    return i&(-i);
}

void update(int idx,int v){
    for(int i=idx;i<=2*n;i+=lowbit(i)){
        c[i]+=v;
    }
}
int getsum(int idx){
    int sum = 0;
    for(int i=idx;i>=1;i-=lowbit(i)){
        sum+=c[i];
    }
    return sum;
}
int main()
{
    int tcase;
    scanf("%d",&tcase);
    while(tcase--){
        memset(c,0,sizeof(c));
        scanf("%d",&n);
        int cnt = 1;
        for(int i=1;i<=n;i++){
            scanf("%d%d",&a[i],&b[i]);
            x[cnt++] = a[i];
            x[cnt++] = b[i];
        }
         int k = 2;
        sort(x+1,x+cnt);
        for(int i=2;i<cnt;i++){
            if(x[i]==x[i-1]) continue;
            x[k++] = x[i];
        }
        for(int i=1;i<=n;i++){
            int l = lower_bound(x+1,x+k,a[i])-(x);
            int r = lower_bound(x+1,x+k,b[i])-(x);
            update(l,1);
            update(r+1,-1);
        }
        int MAX = -1;
        for(int i=1;i<=2*n;i++){
            MAX = max(MAX,getsum(i));
        }
        printf("%d\n",MAX);
    }
    return 0;
}

贪心策略:为起点和终点排序,遇到起点的话多一个站台,遇见终点的话少一个站台。中间过程中最大的值即为结果。

#include <iostream>
#include <cstring>
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
const int N = 100005;
int a[N],b[N],n;

int main()
{
    int tcase;
    scanf("%d",&tcase);
    while(tcase--){
        scanf("%d",&n);
        for(int i=0; i<n; i++)
        scanf("%d%d",&a[i],&b[i]);
        sort(a,a+n);
        sort(b,b+n);
        int ans=0,sum=0;
        int j=0,i=0;
        while(i!=n && j!=n)
        {
            if(b[j]<a[i])
            {
                sum--;
                j++;
            }
            else
            {
                sum++;
                i++;
            }
            ans=max(ans,sum);
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

posted @ 2016-08-12 23:26  樱花庄的龙之介大人  阅读(339)  评论(0编辑  收藏  举报