java P1204 [USACO1.2]挤牛奶Milking Cows

题目描述
三个农民每天清晨 5 点起床,然后去牛棚给三头牛挤奶。

第一个农民在 300 秒 (从 5 点开始计时) 给他的牛挤奶,一直到 1000 秒。第二个农民在 700 秒开始,在 1200 秒结束。第三个农民在 1500 秒开始2100 秒结束。

期间最长的至少有一个农民在挤奶的连续时间为 900 秒 (从 300 秒到 1200 秒),而最长的无人挤奶的连续时间(从挤奶开始一直到挤奶结束)为 300 秒 (从 1200 秒到 1500 秒)。

你的任务是编一个程序,读入一个有 n 个农民挤 n 头牛的工作时间列表,计算以下两点(均以秒为单位):

最长至少有一人在挤奶的时间段。

最长的无人挤奶的时间段。(从有人挤奶开始算起)

输入格式
第一行一个正整数 n

接下来 n 行,每行两个非负整数 l,r,表示一个农民的开始时刻与结束时刻。

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

输入输出样例
输入 #1

3
300 1000
700 1200
1500 2100

输出 #1

900 300

说明/提示
【数据范围】

对于 100% 的数据, 1≤n≤5000,1≤l≤r≤10^6。

题目翻译来自NOCOW。

USACO Training Section 1.2

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class Main {
	int n = 0, m = 0;
	int t1 = 0, t2 = 0;
	int[] a = new int[1000010];
	int[] b = new int[1000010];

	public static void main(String[] args) {
		new Main().na();
	}

	public void na() {
		Scanner in = new Scanner(System.in);

		n = in.nextInt();
		List<Node> nodes = new ArrayList<Node>();

		for (int i = 0; i < n; i++) {
			nodes.add(new Node(in.nextInt(), in.nextInt()));
		}
		Collections.sort(nodes);
		int begin = nodes.get(0).a;
		int end = nodes.get(0).b;
		for (int i = 1; i < n; i++) {
			if (nodes.get(i).a <= end) {
				end = Math.max(end, nodes.get(i).b);
			} else {
				t1 = Math.max(t1, end - begin);
				t2 = Math.max(t2, nodes.get(i).a - end);
				begin = nodes.get(i).a;
				end = nodes.get(i).b;
			}
		}
		t1 = Math.max(t1, end - begin);
		System.out.println(t1 + " " + t2);
	}

}

class Node implements Comparable<Node> {
	int a;
	int b;

	public Node(int a, int b) {
		this.a = a;
		this.b = b;
	}

	@Override
	public int compareTo(Node o) {
		// TODO Auto-generated method stub
		return a - o.a;
	}

	@Override
	public String toString() {
		return "Node [a=" + a + ", b=" + b + "]";
	}

}

思路 :
每个Node类分别存储着时间段的起始点和结束点,先为所以时间段的起始点从小到大排序,选用一个时间段的作为开始与结束,然后第二个的起始点如果比第一个的结束点大,选取下一个时间段的开始与结束作为一个新的开始与结束,那么第一个就不会与后面是所有时间段有关系,因为排序过了。后面是时间段也是同样的,如果后面一个起始点比前面一个的结束点小那么就重新调整当前时间段的结束点为最后的时间段,每次都计算一下新的最长间隔,与空闲时间间隔。

下面这个另一个大佬的

#include<bits/stdc++.h>
using namespace std;
int N; 
struct node
{
	int begin,end;
}m[5005];
bool cmp(node a,node b)
{
	return a.begin<b.begin;
}
int main()
{
	scanf("%d",&N);
	for(register int i=1;i<=N;++i)
		scanf("%d%d",&m[i].begin,&m[i].end);
	sort(m+1,m+1+N,cmp);
	int begin=m[1].begin;
	int end=m[1].end;
	int ans1=0,ans2=0;
	for(register int i=2;i<=N;++i)
	{
		if(m[i].begin<=end)
			end=max(end,m[i].end);
		else
		{
			ans1=max(ans1,end-begin);
			ans2=max(ans2,m[i].begin-end);
			begin=m[i].begin;
			end=m[i].end;
		}
	}
	ans1=max(ans1,end-begin);
	printf("%d %d",ans1,ans2);
 	return 0;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值