USACO 1.2.1 Milking Cows

//译题    
★Milking Cows 挤牛奶
三个农民每天清晨5 点起床,然后去牛棚给3 头牛挤奶.第一个农民在300 时刻(从5 点开始计时,
秒为单位)给他的牛挤奶,一直到1000 时刻.第二个农民在700 时刻开始,在 1200 时刻结束.第三个
农民在1500 时刻开始2100 时刻结束.期间最长的至少有一个农民在挤奶的连续时间为900 秒(从
300 时刻到1200 时刻),而最长的无人挤奶的连续时间(从挤奶开始一直到挤奶结束)为300 秒(从
1200 时刻到1500 时刻).
你的任务是编一个程序,读入一个有N 个农民(1 <= N <= 5000)挤N 头牛的工作时间列表,计算以下
两点(均以秒为单位):
• 最长至少有一人在挤奶的时间段.
• 最长的无人挤奶的时间段.
PROGRAM NAME: milk2
INPUT FORMAT
Line 1: 一个整数N.
Lines 2..N+1: 每行两个小于1000000 的非负整数,表示一个农民的开始时刻与结束时刻.
SAMPLE INPUT (file milk2.in)
3
300 1000
700 1200
1500 2100
OUTPUT FORMAT
一行,两个整数,即题目所要求的两个答案.
SAMPLE OUTPUT (file milk2.out)
900 300
/*
ID: china_l5
LANG: C
TASK: milk2
*/
#include<stdio.h>
#include<math.h>
#define MAXN 5000 + 10

/*
按照开始时间升序排序,然后从左到右扫一遍,复杂度是O(nlogn+n)的(排序+扫一遍,用堆、合并、快排都可以)。
所谓从左到右扫一遍,就是记录一个当前区间,[tmp_begin,tmp_end]。
如果下一组数据的begin比tmp_end的小(或相等),则是连接起来的,检查这组数据的end,取max{end,tmp_end}。
如果下一组数据的begin比tmp_end的大,则是相互断开的,整理本区间,ans1取max{tmp_end - tmp_begin,ans1}。ans2取max{begin - tmp_end,ans2}。
看不懂?去看看PASCAL或C的范例程序就明白了。
线段
*/
void swap(int *a, int *b)    //用于排序 
{
    int  t = *a;
        *a = *b;
        *b = t;
}

int main()
{
    int a[2][MAXN]={0};            //存放n个农民工作的时间区间 
    int i, j, tmp, n;
    int max1=0, max2=0;             //max1存放最长至少有一人在挤奶的时间段.,   max2存放最长的无人挤奶的时间段.
    int cur[2]={0};                //用于存区间,cur[0]存起始时间 cur[1]存结束时间 
    freopen("milk2.in", "r", stdin);        
    freopen("milk2.out", "w", stdout);
    
    scanf("%d", &n);            //读入n 
    for(i=0;i<n;i++)            //读入时间 
        scanf("%d %d",&a[0][i],&a[1][i]);
    for(i=0;i<n-1;i++)            //将时间按照起始时间从小到大排序, 
        for(j=0;j<n-1-i;j++)
        {
            if(a[0][j+1] < a[0][j])
            {
                swap(&a[0][j+1],&a[0][j]);
                swap(&a[1][j+1],&a[1][j]);
            }
        }    
        cur[0]=a[0][0];        //默认起始时间为a{0][0]; 
        cur[1]=a[1][0];
    for(i=1;i<n;i++)         //这里是这题的关键,前面不管你用什么方法,就是排个序就行了 
    {
        if(a[0][i] > cur[1])     //如果本组数据的begin比上一组数据的end的大,说明是有间断存在的
        {
            tmp = a[0][i] - cur[1];    //tmp==无人挤奶的时间
            if(tmp > max2)            //tmp 与 max2进行比较
                    max2 = tmp;
            tmp = cur[1] - cur [0];     //tmp == 上一组数据的时间段
            if(tmp > max1)            
                max1 = tmp;
            cur[0] = a[0][i];            //cur的值改变为本组数据的值
            cur[1] = a[1][i];
        }
        else                                
        {                                            
            if(a[1][i] > cur[1])        //如果本组数据的end > 上一组数据的end
                cur[1] = a[1][i];
        }
    }
    tmp = cur[1] - cur[0];            //求出最大的有人工作的时间
    if(tmp > max1)
        max1 = tmp;
    printf("%d %d
", max1, max2);    
    return 0;
}
原文地址:https://www.cnblogs.com/Lee-geeker/p/3224308.html