【NOIP2013模拟】KC看星

【NOIP2013模拟】KC看星
Time Limits: 1000 ms Memory Limits: 262144 KB
Description

  • “一闪一闪亮晶晶,满天都是小星星”
  • Kc吟唱着歌谣,躺在草坪上边想着她边看起了星星。Kc刚刚结识了笛卡尔这位好基友,认为他的坐标系非常神奇。于是他随机地选出了8颗星星,并且给它们标上了坐标。Kc又不甘寂寞,于是思考起一个问题:这八个点能否恰好构成一个正方形和一个矩形呢?

Input
输入文件包括1行16个数,表示8个星星的坐标,坐标绝对值不超过10000。

Output
输出文件第一行是”YES”或者”NO”。表示是否有解。

若有解则第二行依次输出正方形每个顶点的序号。第三行依次输出矩形每个顶点的序号。序号即为输入的顺序。

另外注意:因为kc是一个刁端的人,所以他要求第二行和第三行这八个数要字典序最小。

四点共线不能认为是正方形或矩形

Sample Input
0 0 10 11 10 0 0 11 1 1 2 2 2 1 1 2

Sample Output
YES
5 6 7 8
1 2 3 4

解题思路:

方法就是暴力!暴力枚举四个点,判断当前四个点是否是正方形,另外四个点是否是长方形就可以了。
但是:该如何判断呢——
1.正方形:暴力全排列枚举四个点的位置(因为给出的数据点的位置有可能没有规律),就是24种方案,倘若有一种方案使得四边相等,对角线相等(可能有平行四边形的状况),则它是正方形。
2.长方形:同样全排列暴力,只要对边相等,对角线相等则就是长方形。
codes:

const
    n=10000000;
    p:array[1..24,1..4]of integer=((1,2,3,4),(1,2,4,3),(1,3,2,4),(1,3,4,2),(1,4,2,3),(1,4,3,2),
                                   (2,1,3,4),(2,1,4,3),(2,3,1,4),(2,3,4,1),(2,4,1,3),(2,4,3,1),
                                   (3,1,2,4),(3,1,4,2),(3,2,1,4),(3,2,4,1),(3,4,1,2),(3,4,2,1),
                                   (4,1,2,3),(4,1,3,2),(4,2,1,3),(4,2,3,1),(4,3,1,2),(4,3,2,1));
var coor:array[1..8,1..2]of longint;
    a,b,c,d:array[1..4,1..2]of longint;
    i,j,k,l,x,y,z,r,o:longint;
    p1,p2:boolean;
function f(x,y,x1,y1:longint):real;
begin
    exit(sqrt(sqr(x-x1)+sqr(y-y1)));
end;
function pan1:boolean;
    var o,x1,x2,y1,y2:longint;
        aa,bb,cc,dd,ee,ff:real;
begin
    aa:=f(a[1,1],a[1,2],a[2,1],a[2,2]);
    bb:=f(a[2,1],a[2,2],a[3,1],a[3,2]);
    cc:=f(a[4,1],a[4,2],a[3,1],a[3,2]);
    dd:=f(a[1,1],a[1,2],a[4,1],a[4,2]);
    ee:=f(a[2,1],a[2,2],a[4,1],a[4,2]);
    ff:=f(a[1,1],a[1,2],a[3,1],a[3,2]);
    if aa<>bb then exit(false);
    if bb<>cc then exit(false);
    if cc<>dd then exit(false);
    if ee<>ff then exit(false);
    exit(true);
end;
function pan2:boolean;
    var o,x1,x2,y1,y2:longint;
        aa,bb,cc,dd,ee,ff:real;
begin
    aa:=f(b[1,1],b[1,2],b[2,1],b[2,2]);
    bb:=f(b[2,1],b[2,2],b[3,1],b[3,2]);
    cc:=f(b[4,1],b[4,2],b[3,1],b[3,2]);
    dd:=f(b[1,1],b[1,2],b[4,1],b[4,2]);
    ee:=f(b[2,1],b[2,2],b[4,1],b[4,2]);
    ff:=f(b[1,1],b[1,2],b[3,1],b[3,2]);
    if aa<>cc then exit(false);
    if bb<>dd then exit(false);
    if ee<>ff then exit(false);
    exit(true);
end;
begin
    for i:=1 to 8 do read(coor[i,1],coor[i,2]);
    for i:=1 to 5 do
        for j:=i+1 to 6 do
            for k:=j+1 to 7 do
                for l:=k+1 to 8 do
                begin
                    c[1]:=coor[i]; c[2]:=coor[j]; c[3]:=coor[k]; c[4]:=coor[l];
                    x:=1;
                    while (x=i)or(x=j)or(x=k)or(x=l) do inc(x);
                    y:=x+1;
                    while (y=i)or(y=j)or(y=k)or(y=l) do inc(y);
                    z:=y+1;
                    while (z=i)or(z=j)or(z=k)or(z=l) do inc(z);
                    r:=z+1;
                    while (r=i)or(r=j)or(r=k)or(r=l) do inc(r);
                    d[1]:=coor[x]; d[2]:=coor[y]; d[3]:=coor[z]; d[4]:=coor[r];
                    p1:=false;
                    p2:=false;
                    for o:=1 to 24 do
                    begin
                        a[1]:=c[p[o,1]]; a[2]:=c[p[o,2]]; a[3]:=c[p[o,3]]; a[4]:=c[p[o,4]];
                        p1:=pan1;
                        if p1 then break;
                    end;
                    if not p1 then continue;
                    for o:=1 to 24 do
                    begin
                        b[1]:=d[p[o,1]]; b[2]:=d[p[o,2]]; b[3]:=d[p[o,3]]; b[4]:=d[p[o,4]];
                        p2:=pan2;
                        if p2 then break;
                    end;
                    if not p2 then continue;
                    writeln('YES');
                    writeln(i,' ',j,' ',k,' ',l);
                    writeln(x,' ',y,' ',z,' ',r);
                    halt;
                end;
        writeln('NO');
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值