Analysis
根据题目所给的条件,可知以任意一个点为端点出发的水平和竖直直线都各只有一条,那么最后构造出的多边形就是唯一的。只要在构造完之后判断是否有线段在非端点处相交即可。可以使用线段树判断,但是这题的数据范围暴力枚举判断就可以过了。
Accepted Code
type
segment=record
a,b:longint;
end;
const
nn=maxlongint shr 1;
var
segx,segy:array[1..20000] of segment;
x,y,p,q,fa:array[-20000..20000] of longint;
n,i,j,ans,minx,maxx,miny,maxy,segxnum,segynum:longint;
bo:boolean;
procedure sort(l,r:longint);
var
i,j,midx,midy,tmp:longint;
begin
i:=l;
j:=r;
midx:=x[(l+r) shr 1];
midy:=y[(l+r) shr 1];
repeat
while ((x[i]<midx) or ((x[i]=midx) and (y[i]<midy))) do
inc(i);
while ((x[j]>midx) or ((x[j]=midx) and (y[j]>midy))) do
dec(j);
if not (i>j) then
begin
tmp:=x[i];
x[i]:=x[j];
x[j]:=tmp;
tmp:=y[i];
y[i]:=y[j];
y[j]:=tmp;
inc(i);
dec(j);
end;
until i>j;
if l<j then
sort(l,j);
if i<r then
sort(i,r);
end;
function getfa(i:longint):longint;
begin
if fa[i]=i then
getfa:=i
else
begin
fa[i]:=getfa(fa[i]);
getfa:=fa[i];
end;
end;
begin
readln(n);
minx:=nn;
maxx:=-nn;
miny:=nn;
maxy:=-nn;
for i:=1 to n do
begin
readln(x[i],y[i]);
if x[i]>maxx then
maxx:=x[i];
if x[i]<minx then
minx:=x[i];
if y[i]>maxy then
maxy:=y[i];
if y[i]<miny then
miny:=y[i];
end;
sort(1,n);
for i:=minx to maxx do
p[i]:=nn;
for i:=miny to maxy do
q[i]:=nn;
ans:=0;
segxnum:=0;
segynum:=0;
for i:=1 to n do
begin
fa[i]:=i;
if p[x[i]]=nn then
p[x[i]]:=i
else
begin
inc(segynum);
segy[segynum].a:=p[x[i]];
segy[segynum].b:=i;
fa[i]:=getfa(p[x[i]]);
ans:=ans+y[i]-y[p[x[i]]];
p[x[i]]:=nn;
end;
if q[y[i]]=nn then
q[y[i]]:=i
else
begin
inc(segxnum);
segx[segxnum].a:=q[y[i]];
segx[segxnum].b:=i;
fa[getfa(q[y[i]])]:=fa[i];
ans:=ans+x[i]-x[q[y[i]]];
q[y[i]]:=nn;
end;
end;
bo:=true;
for i:=2 to n do
bo:=bo and (getfa(i)=getfa(1));
for i:=minx to maxx do
bo:=bo and (p[i]=nn);
for i:=miny to maxy do
bo:=bo and (q[i]=nn);
for i:=1 to segxnum do
for j:=1 to segynum do
bo:=bo and not (((y[segy[j].a]<y[segx[i].a]) and (y[segx[i].a]<y[segy[j].b])) and ((x[segx[i].a]<x[segy[j].a]) and (x[segy[j].a]<x[segx[i].b])));
if bo then
writeln(ans)
else
writeln(0);
end.