【问题描述】
给n个闭区间[ai,bi],选择尽量少的区间覆盖一条指定线段[s,t]。
【样例输入】
1 10
7
2 5
1 4
3 8
3 10
7 10
4 6
1 3
【样例输出】
2
【解题思路】
首先,我们可以将bi小于s的数据都去除,因为这些都是无用的,这样可以减少一些时间复杂度。然后以ai为关键字从小到大进行排序,r赋值为b[1],从第二个开始取,如果当前的ai比上一个取的区间的bi小,记录下当前的bi,选择最大的bi所占的区间,更新r,直到r>=t。
【代码实现】
1 type rec=record 2 a,b:longint; 3 end; 4 var c:array[1..1000] of rec; 5 i,n,s,t,ans,j,r,pos,max:longint; 6 y:rec; 7 procedure sort(l,r: longint); 8 var 9 i,j,x: longint; 10 y:rec; 11 begin 12 i:=l; 13 j:=r; 14 x:=c[(l+r) div 2].a; 15 repeat 16 while c[i].a<x do 17 inc(i); 18 while x<c[j].a do 19 dec(j); 20 if not(i>j) then 21 begin 22 y:=c[i]; 23 c[i]:=c[j]; 24 c[j]:=y; 25 inc(i); 26 j:=j-1; 27 end; 28 until i>j; 29 if l<j then 30 sort(l,j); 31 if i<r then 32 sort(i,r); 33 end; 34 begin 35 readln(s,t); 36 readln(n); 37 for i:=1 to n do 38 with c[i] do 39 begin 40 readln(a,b); 41 if b<=s then 42 a:=maxlongint;//预处理 43 end; 44 sort(1,n); 45 if c[1].a>s then//如果最小的ai比s大,那么s必定无法被覆盖,因此无解 46 begin 47 writeln('No answer'); 48 halt; 49 end; 50 r:=c[1].b;pos:=1;ans:=1;//减少时间复杂度,设pos变量,从上一个所取的区间的后一个开始取 51 repeat 52 max:=0; 53 for i:=pos+1 to n do 54 if (c[i].a<=r)and(c[i].b>max) then 55 begin 56 pos:=i; 57 max:=c[i].b; 58 end; 59 r:=max; 60 inc(ans); 61 until r>=t; 62 writeln(ans); 63 end.