安排值班
题目大意:有n个奶牛,他们负责在长为t个时间点的时间内值班,每个时间点至少有一个在值班,每个奶牛有一段空闲时间可以值班,求满足要求所需最少奶牛数量,无法满足则输出-1.
分析:
将奶牛空闲时间段看成线段,按线段左端点进行排序,排序后从第一个线段开始,每次选择与前一个线段有重合或恰好相接的线段,并在满足此条件同时选择右端点最大的,让该奶牛值班。在选择时要避免选择线段右端点比前一个选择的线段右端点还小或相等的情况,注意处理好首尾线段即可。
代码:
program cleaning; var a,b:array[0..25000]of longint; n,i,m,j,k,t,g,p:longint; procedure qsort(l,h:longint); var i,j,t,m:longint; begin i:=l; j:=h; m:=a[(i+j) div 2]; repeat while a[i]<m do inc(i); while m<a[j] 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 i<h then qsort(i,h); if j>l then qsort(l,j); end; begin assign(input,‘cleaning.in‘); reset(input); assign(output,‘cleaning.out‘); rewrite(output); readln(n,t); for i:=1 to n do read(a[i],b[i]); qsort(1,n); k:=1; for i:=1 to n do begin if a[i]<=k then if (b[i]>m)and(b[i]>=p) then m:=b[i]; if a[i]>k then if a[i]>m+1 then begin writeln(-1); break; end else begin k:=m+1;p:=k; j:=j+1; if m>=t then begin g:=1; break; end; m:=b[i];end; end; if m>=t then if g=0 then writeln(j+1) else writeln(j) else if i=n then writeln(-1); close(input); close(output); end.
时间: 2024-10-20 23:23:10