USACO-Chapter1-Section 1.2-Milking Cows (milk2)
【题目描述】
三个农民每天清晨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..N+1:
每行两个小于1000000的非负整数,表示一个农民的开始时刻与结束时刻。
【输出格式】
一行,两个整数,即题目所要求的两个答案。
【输入样例】
3 300 1000 700 1200 1500 2100
【输出样例】
900 300
【思路】
这是一道类似于线段树的题目,因为数据太小,所以可以在O(n)的时间内查找计算首先对时间从小到大排序,然后用aa,bb分别记录下当前区间的最大最小值,如果新输入的值在此内,跳过,如果不在则判断是否范围比之前的更大,如果是更新。如果改次查找的值下界比区间最大值还大,应该是遇到了间断,此时判断并比较记录。(打擂更替)
【算法代码】
时间复杂度[O(n*log(n)+n)]
空间复杂度[O(n)]
- Executing...
- Test 1: TEST OK [0.000 secs, 316 KB]
- Test 2: TEST OK [0.000 secs, 316 KB]
- Test 3: TEST OK [0.000 secs, 316 KB]
- Test 4: TEST OK [0.000 secs, 316 KB]
- Test 5: TEST OK [0.000 secs, 316 KB]
- Test 6: TEST OK [0.000 secs, 316 KB]
- Test 7: TEST OK [0.000 secs, 316 KB]
- Test 8: TEST OK [0.011 secs, 316 KB]
- All tests OK.
{
ID : c_CaM.19
LANG: PASCAL
TASK: milk2
}
Program CaM(input,output);
Var
a,b:array[0..5100] of longint;
aa,bb,n,ans1,ans2,i,j:longint;
Procedure innt;
Begin
assign(input,'milk2.in'); reset(input);
assign(output,'milk2.out'); rewrite(output);
End;
Function max(x,y:longint):longint;
Begin
if x<y then exit(y) else exit(x);
End;
Procedure outt;
Begin
close(input);
close(output);
End;
Procedure qs(x,y:longint);
Var
mid,i,j,t:longint;
Begin
i:=x; j:=y; mid:=a[(x+y)div 2];
repeat
while a[i]<mid do inc(i);
while a[j]>mid do dec(j);
if i<=j then Begin
t:=a[i]; a[i]:=a[j]; a[j]:=t;
t:=b[i]; b[i]:=b[j]; b[j]:=t;
inc(i); dec(j);
End;
until i>j;
if x<j then qs(x,j);
if i<y then qs(i,y);
End;
Begin
innt;
readln(n);
for i:=1 to n do
read(a[i],b[i]);
qs(1,n);
ans1:=b[1]-a[1]; aa:=a[1]; bb:=b[1];
for i:=2 to n do
Begin
if b[i]<=bb then continue;
if (b[i]>bb)and(a[i]<=bb) then
Begin
ans1:=max(ans1,b[i]-aa);
bb:=b[i];
continue;
End;
if a[i]>bb then
Begin
ans2:=max(ans2,a[i]-bb);
aa:=a[i];
bb:=b[i];
End;
End;
writeln(ans1,' ',ans2);
outt;
End.
浙公网安备 33010602011771号