1. 程式人生 > >USACO milking cows 擠牛奶

USACO milking cows 擠牛奶

Question

Three farmers rise at 5 am each morning and head for the barn to milk three cows. The first farmer begins milking his cow at time 300 (measured in seconds after 5 am) and ends at time 1000. The second farmer begins at time 700 and ends at time 1200. The third farmer begins at time 1500 and ends at time 2100. The longest continuous time during which at least one farmer was milking a cow was 900 seconds (from 300 to 1200). The longest time no milking was done, between the beginning and the ending of all milking, was 300 seconds (1500 minus 1200).

Your job is to write a program that will examine a list of beginning and ending times for N (1 <= N <= 5000) farmers milking N cows and compute (in seconds):

The longest time interval at least one cow was milked.
The longest time interval (after milking starts) during which no cows were being milked.

PROGRAM NAME: milk2

INPUT FORMAT

Line 1: The single integer, N
Lines 2…N+1: Two non-negative integers less than 1,000,000, respectively the starting and ending time in seconds after 0500

SAMPLE INPUT (file milk2.in)

3
300 1000
700 1200
1500 2100

OUTPUT FORMAT

A single line with two integers that represent the longest continuous time of milking and the longest idle time.

SAMPLE OUTPUT (file milk2.out)

900 300

題目描述

三個農民每天清晨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~Line N+1:每行兩個小於1000000的非負整數,表示一個農民的開始時刻與結束時刻。

輸出格式:

一行,兩個整數,即題目所要求的兩個答案。

輸入樣例1:

3
300 1000
700 1200
1500 2100

輸出樣例1:

900 300

解題思路:

我拿輸入樣例1舉例子:在這裡插入圖片描述
先要排序,begin和end分別排,並且保留end[0]和begin[0]分別等於最小的end和begin以免發生錯誤。
然後如果begin[i]比end[i-1]小,代表從begin[i-1]到end[i]的範圍內都是有人的。
如圖即為:
300到1000有人
700到1200有人
因為1000>700
所以300到1200都有人。

之後所做的操作就是數數了
先把有人的時間段都數出來,挑最大值,也就是
end[i]-begin[i]
也就是1000-300=700,1200-300=900,2100-1500=600

然後再數沒有人的時間段
也就是後一個開始到前一個結束的時間差。
300-300=0
300-1000=-700
1500-1200=300
如果最大的時間差也比0小,即所有時間有人,且有時有兩個人時,沒有人的最長時間即為0

程式碼

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int cmp(int a,int b){
	return a<=b;
}
int main(){
//	freopen("milk2.in","r",stdin);
//	freopen("milk2.out","w",stdout);
	int n;
	cin>>n;
	int begin[6000];
	int end[6000];
	begin[0]=0;
	end[0]=0;
	for(int i=1;i<=n;i++){
		scanf("%d %d",&begin[i],&end[i]);
	}
	sort(begin,begin+n+1,cmp);
	sort(end,end+n+1,cmp);
	begin[0]=begin[1];
	end[0]=end[1];
	sort(begin,begin+n+1,cmp);
	sort(end,end+n+1,cmp);
	int have[6000];
	int havent[6000];
	for(int i=1;i<=n;i++){
		have[i]=0;
	}
	for(int i=1;i<=n;i++){
		havent[i]=0;
	}
	for(int i=1;i<=n;i++){
		if(end[i-1]>=begin[i]){
			begin[i]=begin[i-1];
		}
		have[i]=end[i]-begin[i];
	} 
	for(int i=1;i<=n;i++){
		havent[i]=begin[i]-end[i-1];
	}
	sort(have,have+n+1,cmp);
	sort(havent,havent+n+1,cmp);
	if(havent[n]<0){
		havent[n]=0;
	}
	cout<<have[n]<<" "<<havent[n]<<endl;
	return 0;
} 

原創
寫得好累啊


附:
usaco地址:usaco.org
做題地址:train.usaco.org
註冊很煩哦