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;
}


 
原文地址:https://www.cnblogs.com/candy99/p/5791511.html