USACO 1.2 挤牛奶

本文详细解析了USACO 1.2挤牛奶问题,通过离散化方法,枚举时间区间来计算最长挤奶和无人挤奶时间段。适用于算法竞赛训练,特别是针对时间区间处理的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

U S A C O   1.2   挤 牛 奶 USACO\ 1.2\ 挤牛奶 USACO 1.2 

题目链接:SSL 1088

题目

三个农民每天清晨 5 5 5点起床,然后去牛棚给 3 3 3头牛挤奶。第一个农民在 300 300 300时刻(从 5 5 5点开始计时,秒为单位)给他的牛挤奶,一直到 1000 1000 1000时刻。第二个农民在 700 700 700时刻开始,在 1200 1200 1200时刻结束。第三个农民在 1500 1500 1500时刻开始 2100 2100 2100时刻结束。期间最长的至少有一个农民在挤奶的连续时间为 900 900 900秒(从 300 300 300时刻到 1200 1200 1200时刻),而最长的无人挤奶的连续时间(从挤奶开始一直到挤奶结束)为 300 300 300秒(从 1200 1200 1200时刻到 1500 1500 1500时刻)。

你的任务是编一个程序,读入一个有 N N N个农民 ( 1 &lt; = N &lt; = 5000 ) (1 &lt;= N &lt;= 5000) (1<=N<=5000) N N N头牛的工作时间列表,计算以下两点(均以秒为单位):

  1. 最长至少有一人在挤奶的时间段。
  2. 最长的无人挤奶的时间段。

输入

第一行:一个整数 N N N
第二行~第 N + 1 N+1 N+1行:每行两个小于 1000000 1000000 1000000的非负整数,表示一个农民的开始时刻与结束时刻。

输出

一行,两个整数,即题目所要求的两个答案。

样例输入

3
300 1000
700 1200
1500 2100

样例输出

900 300

思路

这道题用离散化来做。

离散化之后,我们枚举每一个时间区间。
如果有人工作,我们就把这个工作的时间加入到连续工作时间,并把连续工作时间和最大连续工作时间比较,取最大值。
如果没有人工作,就把连续工作时间清零,且与最长无人挤奶时间比较,取最大值。

最后,我们只要输出最大连续工作时间和最长无人挤奶时间,就可以了。

代码

#include<cstdio>
#include<algorithm>
#define ll long long
#define max(x, y) (x) > (y) ? (x) : (y) 

using namespace std;

ll n, a[3][5001], b[10001], k, ans, ans1, ans2;

int main() {
	scanf("%lld", &n);//读入
	for (ll i = 1; i <= n; i++) {
		scanf("%lld %lld", &a[1][i], &a[2][i]);//读入
		b[++k] = a[1][i];//标记
		b[++k] = a[2][i];
	}
	
	sort(b + 1, b + k + 1);//离散化
	
	for (ll i = 2; i <= k; i++) {
		bool yes=0;//初始化
		for (ll j = 1; j <= n; j++)//枚举每一个人
			if (b[i] > a[1][j] && b[i] <= a[2][j]) {//判断是否在工作
				ans += b[i] - b[i - 1];//更新连续工作时间
				ans1 = max(ans1, ans);//求出最大值
				yes = 1;//标记
				break;//找到了就退出
			}
		if (!yes) {//没有工作
			ans2 = max(ans2, b[i] - b[i - 1]);//求出最长的无人挤奶时间
			ans = 0;//连续工作时间清零
		}
	}
	
	printf("%lld %lld", ans1, ans2);//输出
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值