题意: 给四个线段,判断是否围成了一个矩形。
思路: 先判定是不是平行四边形,再判断是否有一个角是直角。判定是否是平行四边形可以通过统计顶点数和边长的个数来进行。判断是否有一个角是直角可以通过边向量来判断。
起初我判断是否有一个角是直角通过任取三个顶点,然后通过勾股定理判断是否存在一个直角,想了很久才想到反例,如下:
上面三个点之间就存在直角,但是这个四边形不是矩形,只是平行四边形。
代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<stack>
#include<queue>
#include<utility>
#include<vector>
#include<cmath>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
#include<sstream>
using namespace std;
typedef long long LL;
using namespace std;
struct Point{
int x, y;
Point(){}
Point(int a, int b){x = a; y = b;}
bool operator < (const Point& p)const{
return x<p.x || x==p.x&&y<p.y;
}
};
typedef Point Vec;
int T;
set<Point> spoint;
set<int> sline;
vector<Vec> vec;
int Cal(Point p1, Point p2)
{
return (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y);
}
int main()
{
while(scanf("%d", &T) == 1){
while(T--){
spoint.clear();
sline.clear();
vec.clear();
Point p1, p2;
for(int i=0; i<4; i++){
scanf("%d%d%d%d", &p1.x, &p1.y, &p2.x, &p2.y);
spoint.insert(p1);
spoint.insert(p2);
sline.insert(Cal(p1,p2));
vec.push_back(Vec(p1.x-p2.x, p1.y-p2.y));
}
if(spoint.size() != 4){
printf("NO\n");
continue;
}
if(sline.size()!=2 && sline.size()!=1){
printf("NO\n");
continue;
}
bool flag = false;
for(int i=1; i<4; i++){
if(vec[0].x*vec[i].x+vec[0].y*vec[i].y==0){
flag = true;
break;
}
}
if(flag){
printf("YES\n");
}
else{
printf("NO\n");
}
}
}
return 0;
}