hihocoder #1040 矩形判断(计算几何问题 给8个点的坐标,能否成为一个矩形 【模板思路】)

#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
算法分析:我没有计算几何的模板,这道计算几何基础题就只能自己敲!

要完成这道题:首先需要知道一下知识点!1.一个面积大于0的矩形必会有4个互不相同的顶点2.四条边的权值相等(即邻边相等,四边等边平行四边形)或者 边的权值只有两种值(即临边不相等,而对边相等的平行四边形)3.最后判断是不是有个角是直角(只要找到两个边互相垂直就行了, 即向量的点积运算 )

注意:我在算法的实现的过程中用到了STL的set结构,需要注意的一点是:如果要将一个结构体引入set集合,则必须要对所有结构体的元素进行一种重载运算符的书写。否则就会导致数据的丢失!比如:我插入了点(0, 0),再去插入点(0,1),就可能将丢失(0, 1)点。注意!
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <iostream>
#include <string>
#include <queue>
#include <stack>
#include <set>
#include <algorithm>
#define eps 1e-8
#define PI acos(-1.0)

using namespace std;

struct pointer
{
	int x, y;
	bool operator <(const pointer&dd)const{
        if(x==dd.x){
            return y<dd.y;
        }
        return x<dd.x;
	}
}u, v;

set<pointer>a; //点集
set<int>b; //边集

int line(pointer a, pointer b)
{
    return ((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}
struct vect
{
    int x, y;
}c[4];

int main()
{
	int t;
	int i, j;
	scanf("%d", &t);
	while(t--)
	{
	    if(!a.empty()) a.clear();
	    if(!b.empty()) b.clear();
		for(i=0; i<4; i++)
		{
			scanf("%d %d %d %d", &u.x, &u.y, &v.x, &v.y ); //读入一条边
			a.insert(u); a.insert(v);
            b.insert(line(u, v));
            c[i].x = u.x-v.x;
            c[i].y = u.y-v.y; //构建向量
		}
		if(a.size()!=4){
		    set<pointer>::iterator it=a.begin();

           /* while(it!=a.end())
            {
                printf("%d--%d ", it->x, it->y ); it++;
            } */
            //printf("*******%d\n", a.size());

            printf("NO\n"); continue;
        }
        if(b.size()>2){ //==1是正方形 ==2是长方形
            printf("NO\n"); continue;
        }
        //如果这个四边形只有四个点, 并且只有一个或两个不同大小的边
        bool flag=false;
        for(i=0; i<4; i++)
        {
            for(j=0; j<4; j++){
                if(i!=j){
                    if((c[i].x*c[j].x + c[i].y*c[j].y) ==0 )
                    {
                        flag=true; break;
                    }
                }
            }
            if(flag==true) break;
        }
        if(flag==true ) printf("YES\n");
        else printf("NO\n");
	}
	return 0;
}

时间: 2024-10-05 04:42:06

hihocoder #1040 矩形判断(计算几何问题 给8个点的坐标,能否成为一个矩形 【模板思路】)的相关文章

hihoCoder #1040 (判断是否为矩形)

题目大意:给四条线段,问能否构成一个矩形? 题目分析:先判断能否构成四边形,然后选一条边,看另外三条边中是否为一条与他平行,两条垂直. 代码如下: # include<iostream> # include<cstdio> # include<cmath> # include<set> # include<cstring> # include<algorithm> using namespace std; # define LL lo

hihoCoder 1040 矩阵判断

题目来源:矩阵判断 解题思路: 1.判断矩阵的4个点是否相连,一共输入8个点,只要判断是否4个点是否都经过2遍: 2.判断矩阵中任意一条边与其他边之间要么平行,要么垂直.设A(x1,y1),B(x2,y2),C(x3,y3),D(x4,y4),则线段AB的向量为A’(x2-x1,y2-y1),线段CD的向量C'(x4-x3,y4-y3),另x2-x1=a1,y2-y1=a2,x4-x3=c1,y4-y3=c2,判断A’是否平行C'的方法是a1*c2-a2*c1=0:判断A’是否垂直C'的方法是a

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

http://hihocoder.com/problemset/problem/1040 首先判断四条线段是否相交,给出八个点,如果有一些点重合,并且不同坐标的点只有4个的话,表示可以构成四边形. 然后判断每一条线段与其他线段树平行或者垂直,每一条线段都和其他线段平行或垂直的话就能构成矩形. 平行或相交可以用斜率计算,注意斜率不存在或者等于0的情况. 平行斜率相等,垂直的话斜率相乘等于-1,或者一个不存在一个为0. 1 #include<iostream> 2 #include<cstd

hihoCoder - 1040 - 矩形判断 (简单计算几何~)

#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,表示输入的

[hihoCoder]矩形判断

#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,表示输入的

定义一个矩形和点的位置,判断点是否在矩形里面

25.按要求编写一个Java应用程序: (1)编写一个矩形类Rect,包含: 两个属性:矩形的宽width:矩形的高height. 两个构造方法: 1.一个带有两个参数的构造方法,用于将width和height属性初化: 2.一个不带参数的构造方法,将矩形初始化为宽和高都为10. 两个方法: 求矩形面积的方法area() 求矩形周长的方法perimeter() (2)通过继承Rect类编写一个具有确定位置的矩形类PlainRect,其确定位置用 矩形的左上角坐标来标识,包含: 添加两个属性:矩形

zoj 1608 Two Circles and a Rectangle 判断两个圆是否能放入一个矩形中

题目来源:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=608 分析: 两个圆放到矩形的临界点图为: 其中a为长, b为宽, r1 > r2 红色三角形的三边长分别为: x = a - (r1 +r2) y = b - (r1 + r2) z = r1 +r2 当 x ^ 2 + y ^ 2  >= z^2 时, 显然 矩形是可以放进去圆的. 代码如下: int main() { double w, l , r1 ,r2

25.按要求编写一个Java应用程序: (1)编写一个矩形类Rect,包含: 两个属性:矩形的宽width;矩形的高height。 两个构造方法: 1.一个带有两个参数的构造方法,用于将width和height属性初化; 2.一个不带参数的构造方法,将矩形初始化为宽和高都为10。 两个方法: 求矩形面积的方法area() 求矩形周长的方法perimeter() (2)通过继承Rect类编写一个具有

package zhongqiuzuoye; public class Rect { public double width; public double height; Rect(double width,double height) //带有两个参数的构造方法,用于将width和height属性初化; { this.width=width; this.height=height; } Rect() //不带参数的构造方法,将矩形初始化为宽和高都为10. { width=10; height=

在平面内,已知一个矩形的四个角坐标,将矩形绕中心点转动一个角度,求旋转后的角坐标.

在平面内,已知一个矩形的四个角坐标,将矩形绕中心点转动一个角度,求旋转后的角坐标.也就是已知半径,求每个点旋转后的坐标. 把旋转前和旋转后的点加上中心点看成一个等腰三角形就好解决了,不用扇形公式,而是用三角形公式.假设矩形的左上角为(left, top),右下角为(right, bottom),则矩形上任意点(x0, y0)绕其中心(xcenter,ycenter)逆时针旋转angle角度后,新的坐标位置(x′, y′)的计算公式为: xcenter = (right - left + 1) /