#1040 : 矩形判断
时间限制:1000ms
单点时限:1000ms
内存限制:256MB
-
3 0 0 0 1 1 0 1 1 0 1 1 1 1 0 0 0 0 1 2 3 1 0 3 2 3 2 2 3 1 0 0 1 0 1 1 0 1 0 2 0 2 0 1 1 1 1 0 1
样例输出 -
YES YES NO
描述
给出平面上4条线段,判断这4条线段是否恰好围成一个面积大于0的矩形。
输入
输入第一行是一个整数T(1<=T<=100),代表测试数据的数量。
每组数据包含4行,每行包含4个整数x1, y1, x2, y2 (0 <= x1, y1, x2, y2 <= 100000);其中(x1, y1), (x2,y2)代表一条线段的两个端点。
输出
每组数据输出一行YES或者NO,表示输入的4条线段是否恰好围成矩形。
题解:我们先确定这四条线段是否闭合并且有且只有4个顶点,每个顶点仅访问两次,并且将这四个顶点存放在d数组中。然后对每个顶点及其旁边的两个顶点进行判断是否垂直,也就是用到向量公式如下:
向量a=(x1,y1),向量b=(x2,y2),
a∥b的充要条件(或说成等价于)是x1y2-x2y1=0;
a⊥b的充要条件(或说成等价于)是x1x2+y1y2=0;
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <queue>
#include <map>
#include <stack>
#include <list>
#include <vector>
#include <ctime>
#define LL long long
#define EPS 1e-8
using namespace std;
struct node
{
LL x,y;
}f[5][3];
int pd(LL x,LL y)
{
int i,j;
node s[3];
int t=1;
for (i=1;i<=4;i++)
for (j=1;j<=2;j++)
{
if (f[i][j].x==x && f[i][j].y==y)
{
s[t].x=f[i][3-j].x-x;
s[t].y=f[i][3-j].y-y;
//cout<<s[t].x<<s[t].y<<endl;
t=2;
}
}
int ans=s[1].x*s[2].x+s[1].y*s[2].y;
if (ans!=0) return 1;
return 0;
}
node d[10];
int main()
{
int T,i,j;
scanf("%d",&T);
while (T--)
{
map < pair<LL ,LL> ,int>mp;
for (i=1;i<=4;i++)
for (j=1;j<=2;j++)
{
scanf("%lld%lld",&f[i][j].x,&f[i][j].y);
pair<LL ,LL> t;
t=make_pair(f[i][j].x,f[i][j].y);
mp[t]++;
}
map < pair<LL ,LL> ,int>::iterator it;
int flag=0;
for (it=mp.begin();it!=mp.end();it++)
{
d[flag].x=(*it).first.first;
d[flag].y=(*it).first.second;
flag++;
//cout<<(*it).first.first<<" "<<(*it).first.second<<endl;
if ((*it).second!=2)
{
flag=0;
break;
}
}
if (flag!=4)
{
puts("NO");
continue;
}
flag=1;
for (i=0;i<4;i++)
if (pd(d[i].x,d[i].y))
{
puts("NO");
flag=0;
break;
}
if (flag) puts("YES");
}
return 0;
}