[SGU]128. Snake

来源:互联网 发布:家庭农场管理软件源码 编辑:程序博客网 时间:2024/05/24 03:19

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.


原创粉丝点击