1185: [HNOI2007]最小矩形覆盖 - BZOJ

时间:2023-03-09 00:49:56
1185: [HNOI2007]最小矩形覆盖 - BZOJ

1185: [HNOI2007]最小矩形覆盖 - BZOJ 1185: [HNOI2007]最小矩形覆盖 - BZOJ

就是一道凸包(枚举凸包的边作为矩形的一条边)的裸题,只是不太好打,所以犹豫到今天才打

不说了,说起AC都是泪啊,因为没有精度判断,没有判重(算距离时除0了)错了好久
拍了好久都和标称是一样的,因为我是随机生成数据,基本不可能有重复的点
代码请自动无视...193行pascal(都是一坨一坨的)

 const
eps=1e-7;
var
x,y:array[..]of extended;
s:array[..]of longint;
p:array[..,..]of longint;
n,tot:longint;
sp:extended; procedure swap(var x,y:extended);
var
t:extended;
begin
t:=x;x:=y;y:=t;
end; function min(x,y:extended):extended;
begin
if x<y then exit(x);
exit(y);
end; function cj(x1,y1,x2,y2,x3,y3:extended):extended;
begin
exit((y1-y2)*(x3-x1)+(x2-x1)*(y3-y1));
end; function jl(x1,y1,x2,y2,x3,y3:extended):extended;
begin
exit(cj(x1,y1,x2,y2,x3,y3)/sqrt(sqr(x1-x2)+sqr(y1-y2)));
end; procedure jiao(var x,y:extended;x1,y1,x2,y2,x3,y3:extended);
begin
x3:=x3-x1;
y3:=y3-y1;
if abs(x2)<eps then
begin
x:=x1;
y:=y1+y3;
exit;
end;
if abs(y2)<eps then
begin
x:=x1+x3;
y:=y1;
exit;
end;
x2:=y2/x2;
y3:=y3+x3/x2;
x3:=-/x2;
x:=y3/(x2-x3);
y:=x*x2;
x:=x+x1;
y:=y+y1;
end; procedure sort(l,r:longint);
var
i,j:longint;
xi,yi:extended;
begin
i:=l;
j:=r;
xi:=x[(l+r)>>];
yi:=y[(l+r)>>];
repeat
while (cj(x[],y[],xi,yi,x[i],y[i])<)and(abs(cj(x[],y[],xi,yi,x[i],y[i]))>eps) do
inc(i);
while (cj(x[],y[],xi,yi,x[j],y[j])>)and(abs(cj(x[],y[],xi,yi,x[j],y[j]))>eps) do
dec(j);
if i<=j then
begin
swap(x[i],x[j]);
swap(y[i],y[j]);
inc(i);
dec(j);
end;
until i>j;
if i<r then sort(i,r);
if j>l then sort(l,j);
end; procedure init;
var
i:longint;
minx,miny:extended;
begin
read(n);
minx:=;
miny:=;
for i:= to n do
begin
read(x[i],y[i]);
if (y[i]<miny)or((abs(y[i]-miny)<eps)and(x[i]<minx)) then
begin
minx:=x[i];
miny:=y[i];
end;
end;
i:=;
while i<=n do
if (abs(x[i]-minx)<eps)and(abs(y[i]-miny)<eps) then
begin
swap(x[i],x[n]);
swap(y[i],y[n]);
dec(n);
end
else inc(i);
x[]:=minx;
y[]:=miny;
sort(,n);
inc(n);
x[n]:=x[];
y[n]:=y[];
end; procedure work;
var
i:longint;
begin
for i:= to n do
begin
while (tot>)and(cj(x[s[tot-]],y[s[tot-]],x[s[tot]],y[s[tot]],x[i],y[i])<) do
dec(tot);
inc(tot);
s[tot]:=i;
if (abs(x[s[tot]]-x[s[tot-]])<eps)and(abs(y[s[tot]]-y[s[tot-]])<eps) then dec(tot);
end;
for i:= to tot do
begin
x[i]:=x[s[i]];
y[i]:=y[s[i]];
end;
n:=tot;
for i:= to n do
begin
if jl(-y[],x[],-y[],x[],x[i],y[i])<jl(-y[],x[],-y[],x[],x[p[,]],y[p[,]]) then p[,]:=i;
if jl(x[],y[],x[],y[],x[i],y[i])>jl(x[],y[],x[],y[],x[p[,]],y[p[,]]) then p[,]:=i;
if jl(-y[],x[],-y[],x[],x[i],y[i])>jl(-y[],x[],-y[],x[],x[p[,]],y[p[,]]) then p[,]:=i;
end;
for i:= to n- do
begin
p[i]:=p[i-];
p[i,]:=i;
while jl(-y[i],x[i],-y[i+],x[i+],x[(p[i,]+)mod n],y[(p[i,]+)mod n])<jl(-y[i],x[i],-y[i+],x[i+],x[p[i,]],y[p[i,]]) do
p[i,]:=(p[i,]+)mod n;
while jl(x[i],y[i],x[i+],y[i+],x[(p[i,]+)mod n],y[(p[i,]+)mod n])>jl(x[i],y[i],x[i+],y[i+],x[p[i,]],y[p[i,]]) do
p[i,]:=(p[i,]+)mod n;
while jl(-y[i],x[i],-y[i+],x[i+],x[(p[i,]+)mod n],y[(p[i,]+)mod n])>jl(-y[i],x[i],-y[i+],x[i+],x[p[i,]],y[p[i,]]) do
p[i,]:=(p[i,]+)mod n;
end;
sp:=;
for i:= to n- do
sp:=min(sp,abs((jl(x[i],y[i],x[i+],y[i+],x[p[i,]],y[p[i,]])-jl(x[i],y[i],x[i+],y[i+],x[p[i,]],y[p[i,]]))*(jl(-y[i],x[i],-y[i+],x[i+],x[p[i,]],y[p[i,]])-jl(-y[i],x[i],-y[i+],x[i+],x[p[i,]],y[p[i,]]))));
writeln(sp::);
for i:= to n- do
if abs(abs((jl(x[i],y[i],x[i+],y[i+],x[p[i,]],y[p[i,]])-jl(x[i],y[i],x[i+],y[i+],x[p[i,]],y[p[i,]]))*(jl(-y[i],x[i],-y[i+],x[i+],x[p[i,]],y[p[i,]])-jl(-y[i],x[i],-y[i+],x[i+],x[p[i,]],y[p[i,]])))-sp)<eps then break;
jiao(x[n+],y[n+],x[i],y[i],x[i+]-x[i],y[i+]-y[i],x[p[i,]],y[p[i,]]);
jiao(x[n+],y[n+],x[p[i,]],y[p[i,]],y[i]-y[i+],x[i+]-x[i],x[p[i,]],y[p[i,]]);
jiao(x[n+],y[n+],x[p[i,]],y[p[i,]],x[i+]-x[i],y[i+]-y[i],x[p[i,]],y[p[i,]]);
jiao(x[n+],y[n+],x[p[i,]],y[p[i,]],y[i]-y[i+],x[i+]-x[i],x[i],y[i]);
x[]:=;
y[]:=;
for i:= to do
if (y[n+i]<y[])or((abs(y[]-y[n+i])<eps)and(x[n+i]<x[])) then
begin
x[]:=x[n+i];
y[]:=y[n+i];
end;
for i:= to do
if (abs(x[]-x[n+i])<eps)and(abs(y[]-y[n+i])<eps) then break;
swap(x[n+],x[n+i]);
swap(y[n+],y[n+i]);
writeln(x[]+eps::,' ',y[]+eps::);
sort(n+,n+);
for i:= to do
writeln(x[n+i]+eps::,' ',y[n+i]+eps::);
end; begin
init;
work;
end.