USACO Section 1.2 Milking Cows

题目描述

三名农民每天早晨五点钟起床,并且挤谷仓牛奶三头牛。 第一个农民在时间300开始挤奶他的牛(在上午5点之后以秒为单位),并在时间1000结束。第二个农民在时间700开始,在时间1200结束。第三个农民在时间1500开始,在时间2100结束。 至少有一名农民挤牛时间最长的连续时间是900秒(从300到1200)。 在所有挤奶的开始和结束之间,最长时间没有挤奶,是300秒(1500减去1200)。

您的工作是编写一个程序,将检查N(1 <= N <= 5000)个农民挤奶牛和计算(以秒计)的开始和结束时间列表:
•最长的时间间隔至少有一头牛被挤奶。
•挤奶期间最长的时间间隔(在挤奶开始之后),在此期间没有奶牛被挤奶。

程序名称:milk2

输入格式

第1行:单个整数,N
行2..N + 1:两个非负整数小于1,000,000,分别为0500之后的开始和结束时间(以秒为单位)

输入(file milk2.in)

3
300 1000
700 1200
1500 2100

输出格式
一个单行,表示两个整数,表示最长的连续挤奶时间和最长的空闲时间。

输出(file milk2.out)

900 300
解题思路
本题主要思路是,因为要考虑最长连续挤奶时间和空闲时间,所以我们要对每组数据进行排序,然后前后比较进行判断。两个人的时间段有以下几种情况:
1代表开始,2代表结束,蓝色代表前一个人,红色代表后一个人
一,后一个人的开始在前一个人开始结束之间
1)后一个人的结束也在前一个人开始结束之间
 
 
2)后一个人的结束不在前一个人开始结束之间

 
二,后一个人的开始不在前一个人开始结束之间
 
 
<strong>我们需要分别考虑。</strong>
解题代码
 
/* ID: 15189822 PROG: milk2 LANG: C++ */ #include<iostream> #include<cstdlib> #include<fstream> using namespace std; ofstream fout("milk2.out"); ifstream fin("milk2.in"); int n; struct WorkTime{ int start; int end; }; int cmp(const void *a ,const void *b ){ return (*(WorkTime *)a).start - (*(WorkTime *)b).start; } int main(){ while(fin>>n){ WorkTime *time=new WorkTime[n];//定义一个长度为n的结构体数组 for(int i=0;i<n;i++){//将每个人开始的时间和结束的的时间写入结构体数组 fin>>time[i].start>>time[i].end; } qsort(time,n,sizeof(time[0]),cmp);//将n个人的开始结束时间按照开始时间排序 int maxWork=time[0].end-time[0].start;//最长工作时间 int maxFree=0;//最长空闲时间 for(int i=1,start=time[0].start,end=time[0].end;i<n;i++){ if(time[i].start<=end){ int t=time[i].end-start; if(end<time[i].end){ end=time[i].end; } if(t>maxWork){ maxWork=t; } } else{ int t =time[i].start-end; end =time[i].end; start =time[i].start; if(t>maxFree){ maxFree=t; } t=time[i].end-time[i].start; if(t>maxWork){ maxWork=t; } } } fout<<maxWork<<" "<<maxFree<<endl; delete []time;//释放结构体数组的空间 } return 0; } 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值