JZOJ 3412. 【NOIP2013模拟】KC看星

题目

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
 

Data Constraint

如题

 

分析

 

  • 因为这是个正方形,所以一定会有四边相等。
    同时剩下两条边不会与这四边相等,而且这两条边也互相相等。
    这相等的四边是正方形的边,而另外两边是对角线。
    矩形的情况也类似:
    最短的两边是宽,接着是长,最长的是对角线。
    只要配个对就行了。
    (比赛时没有考虑正方形也是矩形的一种,然后分边时把长分到短的一组里去了……)

 

代码

 

 1 #include<cstdio>
 2 #include<cmath>
 3 using namespace std;
 4 #define s 0.000000005
 5 double x[10],y[10];
 6 int a[5],ans1[5],ans2[5],aa[5];
 7 bool b[10];
 8 inline double sqr(double num){return num*num;}
 9 double dis(int m,int n){return sqrt(sqr(x[n]-x[m])+sqr(y[n]-y[m]));}
10 bool square(int k)
11 {
12     if(k>4)
13     {
14         if(abs(dis(aa[1],aa[2])-dis(aa[2],aa[3]))<s&&abs(dis(aa[1],aa[2])-dis(aa[3],aa[4]))<s&&abs(dis(aa[1],aa[2])-dis(aa[1],aa[4]))<s
15         &&abs(dis(aa[1],aa[3])-dis(aa[2],aa[4]))<s)
16             return 1;
17     }
18     else
19     {
20         int i;bool d;
21         for(i=1;i<=8;i++) if(!b[i])
22         {
23             b[i]=1;aa[k]=i;
24             d=square(k+1);
25             b[i]=0;
26             if(d) return 1;
27         }
28     }
29     return 0;
30 }
31 bool rectangular(int k)
32 {
33     if(k>4)
34     {
35         if(abs(dis(aa[1],aa[2])-dis(aa[3],aa[4]))<s&&abs(dis(aa[2],aa[3])-dis(aa[1],aa[4]))<s&&abs(dis(aa[1],aa[3])-dis(aa[2],aa[4]))<s)
36             return 1;
37     }
38     else
39     {
40         int i;bool d;
41         for(i=1;i<=8;i++) if(b[i])
42         {
43             b[i]=0;aa[k]=i;
44             d=rectangular(k+1);
45             b[i]=1;
46             if(d) return 1;
47         }
48     }
49     return 0;
50 }
51 void dfs(int k,int last)
52 {
53     int i,j;
54     if(k>4)
55     {
56         if(square(1)&&rectangular(1))
57         {
58             for(i=1;i<5;i++) ans1[i]=a[i];
59             for(j=0,i=1;i<9;i++) if(b[i]) ans2[++j]=i;
60         }
61     }
62     else
63     {
64         for(i=last;i<=ans1[k];i++)
65         {
66             b[i]=0;a[k]=i;
67             dfs(k+1,i+1);
68             b[i]=1;
69         }
70     }
71 }
72 int main()
73 {
74     int i;
75     for(i=1;i<9;i++) scanf("%lf%lf",&x[i],&y[i]),b[i]=1;
76     for(i=1;i<5;i++) ans1[i]=ans2[i]=8;
77     dfs(1,1);
78     if(ans1[1]<8||ans1[2]<8)
79     {
80         puts("YES");
81         for(i=1;i<4;i++) printf("%d ",ans1[i]);
82         printf("%d
",ans1[4]);
83         for(i=1;i<4;i++) printf("%d ",ans2[i]);
84         printf("%d
",ans2[4]);
85     }
86     else puts("NO");
87     return 0;
88 }
原文地址:https://www.cnblogs.com/zjzjzj/p/11759259.html