Description
三个农民每天清晨5点起床,然后去牛棚给3头牛挤奶。第一个农民在300时刻(从5点开始计时,秒为单位)给他的牛挤奶,一直到1000时刻。第二个农民在700时刻开始,在 1200时刻结束。第三个农民在1500时刻开始2100时刻结束。期间最长的至少有一个农民在挤奶的连续时间为900秒(从300时刻到1200时刻),而最长的无人挤奶的连续时间(从挤奶开始一直到挤奶结束)为300时刻(从1200时刻到1500时刻)。 你的任务是编一个程序,读入一个有N个农民(1 <= N <= 5000)挤N头牛的工作时间列表,计算以下两点(均以秒为单位): 最长至少有一人在挤奶的时间段。 最长的无人挤奶的时间段。(从有人挤奶开始算起)
Input
Line 1: 一个整数N。 Lines 2..N+1: 每行两个小于1000000的非负整数,表示一个农民的开始时刻与结束时刻。
Output
一行,两个整数,即题目所要求的两个答案。
Sample Input
3 300 1000 700 1200 1500 2100
Sample Output
900 300
解题思路:贪心策略,先按挤牛奶的开始时间升序,开始时间相同,按结束时间升序。如果后面一人的开始时间小于前面一人的结束时间,
说明这段时间内至少有一个人在挤牛奶,
那么把后面一人的结束时间更新为新的至少一人挤牛奶时间段的结束时间,以此类推;反之后面一人开始时间大于前面一人的结束时间,
说明存在无人挤奶时间,需要记录先这一段时间,存入数组中。最后找到最大的至少一人挤奶时间和无人挤奶时间。
上代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 struct message 6 { 7 int start; 8 int end; 9 } a[1000000]; 10 int my_comp(message a,message b) 11 { 12 if(a.start<b.start) 13 return 1; 14 else 15 { 16 if(a.start==b.start) 17 { 18 if(a.end<b.end) 19 return 1; 20 else 21 return 0; 22 } 23 else 24 return 0; 25 } 26 } 27 int main() 28 { 29 int i,j,n,k=0,g=0,ans1=0,ans2=0; 30 int x[10000],y[10000]; 31 struct message t; 32 scanf("%d",&n); 33 memset(x,0,sizeof(x)); 34 memset(y,0,sizeof(y)); 35 for(i=0; i<n; i++) 36 { 37 scanf("%d%d",&a[i].start,&a[i].end); 38 } 39 sort(a,a+n,my_comp); 40 t=a[0]; 41 for(i=1; i<n; i++) 42 { 43 if(a[i].start<=t.end) 44 { 45 if(a[i].end>t.end) 46 t.end=a[i].end; 47 } 48 else 49 { 50 x[k++]=t.end-t.start;///至少一个人挤奶 51 y[g++]=a[i].start-t.end;///无人挤奶 52 t.start=a[i].start; 53 t.end=a[i].end; 54 } 55 } 56 if(k==0)///只有一个人时 57 { 58 x[k++]=t.end-t.start; 59 } 60 for(i=0; i<k; i++) 61 { 62 if(x[i]>ans1) 63 ans1=x[i]; 64 } 65 for(i=0; i<g; i++) 66 { 67 if(y[i]>ans2) 68 ans2=y[i]; 69 } 70 printf("%d %d\n",ans1,ans2); 71 return 0; 72 }