对于每个建筑,放雷达能满足要求的点一定是x轴上的连续一段,给出圆心个半径即可列方程解出每个建筑对应线段的左右端点。问题转化为一个经典的贪心问题,怎样选出数量最少的点使得每一条线段都能包含一个点。先按左端点排序,我们维护上一个加入的点可以安置的区间的右端点,如果当前线段跟这个区间有交集就不用再放雷达,并且更新允许的区间,否而就要再放一个雷达。
Code uses math; var ans,x0,y0,n,r,i:longint; a,b:array[1..1000] of extended; right,delta:extended; procedure swap(var a,b:extended); var t:extended;begin t:=a;a:=b;b:=t;end; function small(x,y:longint):boolean; begin if a[x]<a[y] then exit(true) else if a[x]>a[y] then exit(false)else if b[x]<b[y] then exit(true) else exit(false); end; procedure Qsort(l,r:longint); var i,j:longint; mida,midb:extended; begin i:=l;j:=r;mida:=a[(l+r)>>1];midb:=b[(l+r)>>1]; repeat while(i<r)and((a[i]<mida)or((a[i]=mida)and(b[i]<midb)))do inc(i); while(l<j)and((mida<a[j])or((mida=a[j])and(midb<b[j])))do dec(j); if i<=j then begin swap(a[i],a[j]); swap(b[i],b[j]); inc(i);dec(j); end; until i>j; if(i<r)then Qsort(i,r); if(l<j)then Qsort(l,j); end; begin readln(n,r); for i:=1 to n do begin readln(x0,y0); delta:=-4*y0*y0+4*R*R; if -4*y0*y0+4*R*R<0 then begin writeln('-1'); halt; end; a[i]:=x0-sqrt(delta)/2; b[i]:=x0+sqrt(delta)/2; end; Qsort(1,n); right:=b[1];ans:=1; for i:=2 to n do begin right:=min(right,b[i]); if a[i]>right then begin inc(ans); right:=b[i]; end; end; writeln(ans); end.