hiho 矩形判断

#1040 : 矩形判断

时间限制:1000ms
单点时限:1000ms
内存限制:256MB

描述

给出平面上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条线段是否恰好围成矩形。

样例输入
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个顶点,每个顶点仅访问两次,并且将这四个顶点存放在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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值