原题链接
考察:计算几何,枚举
思路:
枚举所有线段排列方案.检查以下条件:
- 两条线平行,相连两条线垂直.
- 边的长度都\(>0\)
- 都是直角
判断向量平行和垂直: GO
Code
#include <iostream>
#include <cstring>
#include <map>
#include <cmath>
using namespace std;
const int N = 10;
typedef long long LL;
typedef pair<int,int> PII;
struct Node{
int x1,y1,x2,y2;
LL dist;
}node[N];
map<PII,int> mp;
double Dist(Node i)
{
LL d = (LL)(i.x1-i.x2)*(i.x1-i.x2)+(LL)(i.y1-i.y2)*(i.y1-i.y2);
return d;
}
bool ck_px(Node s,Node e)
{
int a = s.x1-s.x2,b = s.y1-s.y2;
int c = e.x1-e.x2,d = e.y1-e.y2;
if(a&&b) return 0;
if(c&&d) return 0;
if(!a&&!c) return 1;
if(!d&&!b) return 1;
return 0;
}
bool ck_cz(Node s,Node e)
{
int a = s.x1-s.x2,b = s.y1-s.y2;
int c = e.x1-e.x2,d = e.y1-e.y2;
LL z = (LL)a*c+(LL)b*d;
return z==0;
}
bool check()
{
for(auto& it:mp)
if(it.second!=2) return 0;
for(int i=1;i<=4;i++)
if(node[i].dist)
for(int j=1;j<=4;j++)
if(j!=i&&node[j].dist)
for(int k=1;k<=4;k++)
if(k!=j&&k!=i&&node[k].dist)
for(int t=1;t<=4;t++)
if(t!=k&&t!=j&&t!=i&&node[t].dist)
{
if(node[i].dist+node[j].dist!=node[k].dist+node[t].dist) continue;
if(node[i].dist+node[t].dist!=node[k].dist+node[j].dist) continue;
if(node[i].dist!=node[k].dist) continue;
if(node[j].dist!=node[t].dist) continue;
if(!ck_px(node[i],node[k])||!ck_px(node[j],node[t])) continue;
if(!ck_cz(node[i],node[j])||!ck_cz(node[j],node[k])||!ck_cz(node[k],node[t])||!ck_cz(node[t],node[i])) continue;
return 1;
}
return 0;
}
int main()
{
for(int i=1;i<=4;i++)
{
int a,b,c,d;
scanf("%d%d%d%d",&a,&b,&c,&d);
mp[{a,b}]++,mp[{c,d}]++;
node[i] = {a,b,c,d};
node[i].dist = Dist(node[i]);
}
if(check()) puts("YES");
else puts("NO");
return 0;
}