2338: [HNOI2011]数矩形 - BZOJ

时间:2023-03-09 08:30:34
2338: [HNOI2011]数矩形 - BZOJ

2338: [HNOI2011]数矩形 - BZOJ

因为已经看了一眼题解,知道是算中点和长度,相同时构成一个矩形,所以就把所有的线段算出来,然后排序,相同的就更新答案

为了避免误差,我们都用整数存,中点直接相加就行了,没必要除2,长度也只要平方就行了,不用开根,算面积就用叉积算,这样做就完全没有误差了

虽然复杂度本来是不行的但是出题人没想卡咱,就过了

 const
maxn=;
type
point=record
x,y:longint;
end;
segment=record
aa,bb:point;
x,y:longint;
l:int64;
end;
var
a:array[..maxn]of point;
seg:array[..maxn*maxn]of segment;
n,tot:longint;
ans:int64; procedure swap(var x,y:segment);
var
t:segment;
begin
t:=x;x:=y;y:=t;
end; procedure sort(l,r:longint);
var
i,j:longint;
x:segment;
begin
i:=l;
j:=r;
x:=seg[(l+r)>>];
repeat
while (x.x<seg[i].x) or ((x.x=seg[i].x) and (x.y<seg[i].y)) or ((x.x=seg[i].x) and (x.y=seg[i].y) and (x.l<seg[i].l)) do
inc(i);
while (x.x>seg[j].x) or ((x.x=seg[j].x) and (x.y>seg[j].y)) or ((x.x=seg[j].x) and (x.y=seg[j].y) and (x.l>seg[j].l)) do
dec(j);
if i<=j then
begin
swap(seg[i],seg[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,j:longint;
begin
read(n);
for i:= to n do
with a[i] do
read(x,y);
for i:= to n- do
for j:=i+ to n do
begin
inc(tot);
with seg[tot] do
begin
aa:=a[i];
bb:=a[j];
x:=a[i].x+a[j].x;
y:=a[i].y+a[j].y;
l:=sqr(int64(a[i].x-a[j].x))+sqr(int64(a[i].y-a[j].y));
end;
end;
sort(,tot);
end; function cj(a,b,c:point):int64;
begin
exit(abs(int64(a.x-b.x)*int64(c.y-b.y)-int64(c.x-b.x)*int64(a.y-b.y)));
end; procedure up(var x:int64;y:int64);
begin
if x<y then x:=y;
end; procedure work;
var
l,r,i,j:longint;
begin
l:=;
r:=;
while l<=tot do
begin
while (r<tot) and (seg[r+].x=seg[l].x) and (seg[r+].y=seg[l].y) and (seg[r+].l=seg[l].l) do
inc(r);
for i:=l to r- do
for j:=i+ to r do
up(ans,cj(seg[i].aa,seg[i].bb,seg[j].aa));
l:=r+;
r:=l;
end;
write(ans);
end; begin
init;
work;
end.