hihoCoder 1040 矩形判断(计算几何)

时间:2023-02-10 17:18:10

http://hihocoder.com/problemset/problem/1040

首先判断四条线段是否相交,给出八个点,如果有一些点重合,并且不同坐标的点只有4个的话,表示可以构成四边形。

然后判断每一条线段与其他线段树平行或者垂直,每一条线段都和其他线段平行或垂直的话就能构成矩形。

平行或相交可以用斜率计算,注意斜率不存在或者等于0的情况。

平行斜率相等,垂直的话斜率相乘等于-1,或者一个不存在一个为0.

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 using namespace std;
 7 double maxn = 1000000;
 8 struct point
 9 {
10     int x,y;
11 }p[10];
12 
13 bool check()
14 {
15     int m=8;
16     for(int i=0;i<8;i++)
17         for(int j=i+1;j<8;j++)
18         if(p[i].x==p[j].x&&p[i].y==p[j].y) m--;
19     if(m==4) return true;
20     return false;
21 }
22 
23 double solve(point a,point b)
24 {
25     if(a.x==b.x) return maxn;
26     else if(a.y==b.y) return 0;
27     else return 1.0*(a.y-b.y)/(a.x-b.x);
28 }
29 int main()
30 {
31     //freopen("a.txt","r",stdin);
32     int t;
33     double k[5];
34     scanf("%d",&t);
35     while(t--)
36     {
37         for(int i=0;i<8;i++) scanf("%d%d",&p[i].x,&p[i].y);
38         if(check()==0) {printf("NO\n");continue;}  //检测是否构成四边形
39         memset(k,0,sizeof(k));
40         int z=0;
41         for(int i=0;i<7;i+=2)
42         {
43             k[z++]=solve(p[i],p[i+1]); //计算每一条线段的斜率
44            // printf("%.3lf\n",k[z-1]);
45         }
46         bool flag=0;
47         for(int i=0;i<4;i++)
48         {     //判断两条线段的关系 
49             for(int j=0;j<4;j++)
50             {
51                 if((k[i]==k[j])||(k[i]==maxn&&k[j]==0)||(k[i]==0&&k[j]==maxn)||(k[i]*k[j]==-1)) continue;
52                 else {flag=1;break;}
53             }
54             if(flag) break;
55         }
56         if(flag) printf("NO\n");
57         else printf("YES\n");
58     }
59     return 0;
60 }