USACO1.2Milking Cows
题目描述
三个农民每天清晨5点起床,然后去牛棚给3头牛挤奶。第一个农民在300秒(从5点开始计时)给他的牛挤奶,一直到1000秒。第二个农民在700秒开始,在 1200秒结束。第三个农民在1500秒开始2100秒结束。期间最长的至少有一个农民在挤奶的连续时间为900秒(从300秒到1200秒),而最长的无人挤奶的连续时间(从挤奶开始一直到挤奶结束)为300秒(从1200秒到1500秒)。
你的任务是编一个程序,读入一个有N个农民(1 <= N <= 5000)挤N头牛的工作时间列表,计算以下两点(均以秒为单位):
最长至少有一人在挤奶的时间段。
最长的无人挤奶的时间段。(从有人挤奶开始算起)
输入输出格式
输入格式:
Line 1:
一个整数N。
Lines 2..N+1:
每行两个小于1000000的非负整数,表示一个农民的开始时刻与结束时刻。
输出格式:
一行,两个整数,即题目所要求的两个答案。
输入输出样例
输入样例#1:
3 300 1000 700 1200 1500 2100
输出样例#1:
900 300
---------------------------------------------------------------------------------
记录每个时间点的时间和是开始还是结束,然后排序,相同时间开始放在前面[防止两人同一时间一个开始一个结束把当前连续时间给清零了]
然后愉快的扫描维护就好了,flag表示当前有没有人,last是上一个时间,tmp12是当前连续的时间
// // main.cpp // usacomilk // // Created by abc on 16/8/20. // Copyright © 2016年 abc. All rights reserved. // #include <iostream> #include <cstdio> #include <algorithm> using namespace std; const int N=5005,L=1e6+5; inline int read(){ char c=getchar(); int x=0,f=1; while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } int n,flag=0,last=0,tmp1=0,tmp2=0,ans1=0,ans2=0; struct second{ int t,left,i; }tm[N<<1]; bool cmp(second a,second b){ if(a.t==b.t) return a.left==1?1:0; return a.t<b.t; } int main(int argc, const char * argv[]) { n=read(); for(int i=1;i<=n;i++){ int a=2*i-1,b=2*i; tm[a].t=read();tm[a].left=1;tm[a].i=a; tm[b].t=read();tm[b].left=0;tm[b].i=b; } sort(tm+1,tm+1+n*2,cmp); last=tm[1].t; for(int i=1;i<=n*2;i++){ if(flag==0){ tmp2+=tm[i].t-last; ans2=max(ans2,tmp2); tmp1=0; } if(flag>=1){ tmp1+=tm[i].t-last; ans1=max(ans1,tmp1); tmp2=0; } if(tm[i].left) flag++;else flag--; last=tm[i].t; } printf("%d %d",ans1,ans2); return 0; }
Copyright:http://www.cnblogs.com/candy99/