题目大意:求在x轴上放一些半径为d的圆,问至少多少个能将n个点覆盖,多组询问。
解:原来想着:线段树+heap,可是看着这一个个0ms,不敢切,以后有时间切切看虐自己。正解是先把可行圆心区间求出来,然后求最多的不互斥区间(因为区间相斥的话,说明有共点,于是不用分配多一个雷达了),证明是首先如果当前l>rrr,inc(s), 若有l<rrr and r<rrr则新预设雷达于r,rrr:=r;
好像有种隐约敢,说不出来,好难受,还是以后想透彻了再补
本题的trick点也很多,例如,d<0, y<0,注意y=0竟然是合法的!!wa了两次,囧
View Code
1 //RadarInstallation 2 const 3 maxn=1111; 4 inf='1.txt'; 5 def=1e-10; 6 type 7 data=record 8 l, r: double; 9 end;10 var11 line: array[0..maxn]of data;12 test, n, d, ans: longint;13 procedure qsort(b, e: longint);14 var15 i, j: longint;16 x: double;17 k: data;18 begin19 i := b; j := e; x := line[(i+j)>>1].l;20 repeat21 while line[i].lx do dec(j);23 if i<=j then begin24 k := line[i]; line[i] := line[j]; line[j] := k;25 inc(i); dec(j);26 end;27 until i>j;28 if j>b then qsort(b, j);29 if i d) then begin ans := -1; continue; end;42 if y=d then tmp := 043 else tmp := sqrt(sqr(d)-sqr(y));44 l := x - tmp; r := x + tmp;45 end;46 end;47 if ans=-1 then exit;48 qsort(1, n);49 end;50 51 procedure main;52 var53 rrr: double;54 i: longint;55 begin56 rrr := -maxlongint;57 for i := 1 to n do with line[i] do begin58 if l{ +def}>rrr then begin59 inc(ans);60 rrr := r;61 end62 else begin63 if r 0)or(d<>0) do begin78 inc(test);79 init;80 if ans=0 then main;81 print;82 readln;83 readln(n, d);84 end;85 end.