{ delphi } (* Problem: TABLE * Contest: UOI-2004 (Kharkiv) * Type: Solution * Author: Andrey Sereda * Date: April 1, 2004 * Language: Pascal * Compiler: Delphi 5.0 * Algorithm: O(N*log N) Solution *) program table; {$APPTYPE CONSOLE} uses SysUtils; const maxn=13000; const maxhash=500; type tdist=extended; pnode=^node; node=record p:pnode; n:integer; end; var f,f1:text; tr,n,i,kr,j:integer; dhash,xl,xr,r,xx,yy,minx,maxx,miny,maxy:longint; hnx,hny,dh,hx,hy:integer; x,y:array[1..maxn]of longint; color:array[0..maxn+1]of integer; resh,d,maxd:tdist; ang:real; reba,rebb:array[1..maxn*10]of integer; rebl:array[1..maxn*10]of tdist; p6n:array[0..5]of integer; p6l:array[0..5]of tdist; sqrt3:extended; hasht:array[0..maxhash,0..maxhash] of pnode; pn:pnode; function dm(a,b:longint):tdist; var x1,x2:tdist; begin x1:=a; x2:=b; dm:=a-b; end; function dist(i,j:integer):tdist; begin dist:=sqr(dm(x[i],x[j]))+sqr(dm(y[i],y[j])); end; procedure sort(l,r:longint); var i,j,p:integer; m,pd:tdist; begin i:=l; j:=r; m:=(rebl[i]+rebl[j])/2; // optim... repeat while rebl[i]j) then begin p:=reba[i]; reba[i]:=reba[j]; reba[j]:=p; p:=rebb[i]; rebb[i]:=rebb[j]; rebb[j]:=p; pd:=rebl[i]; rebl[i]:=rebl[j]; rebl[j]:=pd; inc(i); dec(j); end; until i>j; if lcolor[c1] do c1:=color[c1]; lookcolor:=c1; while c<>c1 do begin c2:=color[c]; color[c]:=c1; c:=c2; end; end; procedure fill(na,nb:integer); var i,ca,cb:integer; begin if random(2)=0 then begin ca:=color[na]; cb:=color[nb]; end else begin cb:=color[na]; ca:=color[nb]; end; while ca<>color[ca] do ca:=color[ca]; while cb<>color[cb] do cb:=color[cb]; color[ca]:=cb; end; procedure workwp(j:integer); var rr:extended; begin if i=j then exit; d:=dist(i,j); xx:=x[i]-x[j]; yy:=y[i]-y[j]; rr:=sqrt3*abs(xx)-abs(yy); if (rr>=0) then // if (abs(sqrt3*xx)>=abs(yy)) then begin if xx>=0 then begin if (yy>=0)and(d=0)and(d=0)and(dnil do begin n:=p^.n; workwp(n); p:=p^.p; end; end; procedure workwdh(hx,hy,dh:integer); var i,j:integer; begin for i:=hx-dh to hx+dh do if (i>=0)and(i<=hnx) then begin if hy-dh>=0 then workwc(i,hy-dh); if hy+dh<=hny then workwc(i,hy+dh); end; for j:=hy-dh+1 to hy+dh-1 do if (j>=0)and(j<=hny) then begin if hx-dh>=0 then workwc(hx-dh,j); if hx+dh<=hnx then workwc(hx+dh,j); end; end; begin sqrt3:=sqrt(3.0); assign(f,'table.dat'); assign(f1,'table.sol'); reset(f); rewrite(f1); readln(f,xl,xr); readln(f,r); readln(f,n); minx:=2000000000; maxx:=-2000000000; miny:=2000000000; maxy:=-2000000000; for i:=1 to n do begin readln(f,x[i],y[i]); if x[i]>maxx then maxx:=x[i]; if y[i]>maxy then maxy:=y[i]; if x[i]1) do dhash:=dhash div 2; while ( (maxx-minx) div dhash+1>maxhash)or((maxy-miny)div dhash+1>maxhash) do dhash:=dhash*2; hnx:=(maxx-minx) div dhash; hny:=(maxy-miny) div dhash; for i:=0 to hnx do for j:=0 to hny do hasht[i,j]:=nil; { add to hash } for i:=1 to n do begin xx:=(x[i]-minx)div dhash; yy:=(y[i]-miny)div dhash; new(pn); pn^.p:=hasht[xx,yy]; pn^.n:=i; hasht[xx,yy]:=pn; end; kr:=0; for i:=1 to n do begin { add 2 base rebra } inc(kr); reba[kr]:=0; rebb[kr]:=i; rebl[kr]:=sqr(dm(x[i],xl-r)); // rebl[kr]:=dm(x[i],xl-r); inc(kr); reba[kr]:=n+1; rebb[kr]:=i; rebl[kr]:=sqr(dm(xr+r,x[i])); // rebl[kr]:=dm(xr+r,x[i]); { find 6 points } for j:=0 to 5 do begin p6l[j]:=1e20; p6n[j]:=-1; end; hx:=(x[i]-minx)div dhash; hy:=(y[i]-miny)div dhash; workwc(hx,hy); dh:=0; maxd:=1e20; while (maxd>sqr(1.0*dhash*dh))and((dh<=hnx)or(dh<=hny)) do begin inc(dh); workwdh(hx,hy,dh); maxd:=0; for j:=0 to 5 do if maxd0)and(ilookcolor(n+1) do begin inc(tr); while lookcolor(reba[tr])=lookcolor(rebb[tr]) do inc(tr); fill(reba[tr],rebb[tr]); end; { output } resh:=sqrt(rebl[tr])-2.0*r; // resh:=rebl[tr]-2.0*r; if resh<0 then resh:=0; writeln(f1,resh:3:3); { writeln(resh:3:3); readln; } close(f); close(f1); end.