POJ 1328

 

题目大意:求在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 var
11         line: array[0..maxn]of data;
12         test, n, d, ans: longint;
13 procedure qsort(b, e: longint);
14 var
15         i, j: longint;
16         x: double;
17         k: data;
18 begin
19   i := b; j := e; x := line[(i+j)>>1].l;
20   repeat
21     while line[i].l<x do inc(i);
22     while line[j].l>x do dec(j);
23     if i<=j then begin
24       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<e then qsort(i, e);
30 end;
31 
32 procedure init;
33 var
34         i, x, y: longint;
35         tmp: double;
36 begin
37   ans := 0;
38   for i := 1 to n do begin
39     readln(x, y);
40     with line[i] do begin
41       if (y<0)or(y>d) then begin ans := -1; continue; end;
42       if y=d then tmp := 0
43       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 var
53         rrr: double;
54         i: longint;
55 begin
56   rrr := -maxlongint;
57   for i := 1 to n do with line[i] do begin
58     if l{+def}>rrr then begin
59       inc(ans);
60       rrr := r;
61     end
62     else begin
63       if r<rrr then rrr := r;
64     end;
65   end;
66 end;
67 
68 procedure print;
69 begin
70   writeln('Case ',test,': ', ans);
71 end;
72 
73 begin
74   assign(input,inf); reset(input);
75   readln(n, d);
76   test := 0;
77   while (n<>0)or(d<>0) do begin
78     inc(test);
79     init;
80     if ans=0 then main;
81     print;
82     readln;
83     readln(n, d);
84   end;
85 end.
posted @ 2012-05-05 11:28  F.D.His.D  阅读(201)  评论(0编辑  收藏  举报