csu 1757(贪心或者树状数组)
1757: 火车入站
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 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; }