矩形判断

  给出平面上4条线段,判断这4条线段是否恰好围成一个面积大于0的矩形。

Input

  输入第一行是一个整数T(1<=T<=100),代表测试数据的数量。

  每组数据包含4行,每行包含4个整数x1, y1, x2, y2 (0 <= x1, y1, x2, y2 <= 100000);其中(x1, y1), (x2,y2)代表一条线段的两个端点。

Output

  每组数据输出一行YES或者NO,表示输入的4条线段是否恰好围成矩形。

Sample Input

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

Sample Output

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

题目解析
  本题给出测试数量t,每组测试给出4条线段,要求判断四条线段是否能围成矩形。

  本题的数据量t很少,不会超过100,且每条线段有两个端点每组数据4条线段,所以不同的点不会超过8个,所有测试数据中包含的不同的点不会超过800个,这样我们就可以放心大胆的浪费内存空间了。

  一、若给出的4条线段可以围成矩形,那么其中必定包含4个不同的端点,利用set的不重复性记录一下4条线段的所有端点,若最后set中的端点不为四个,那这4条线段肯定不能围成一个矩形。

  二、若给出的4条线段可以围成矩形,所以围成的图形一定是个封闭图形,4个端点的度一定为2,利用map建立每个端点和其连通端点集的映射,检查每个端点对应连通集合中是否只有两个端点,若不为两个端点,那这4条线段肯定不能围成一个矩形。

  三、若给出的4条线段可以围成矩形,则每条线段都会有另一条长度相等的线段与其平行,用vector保存每个线段对应的向量,则若存在两条长度相等且平行的线段,其对应向量相等或符号相反,之后遍历所有向量,与其相等或符号相反的向量定有其本身加上平行相等线段对应的向量共两条,若不为两条那这4条线段肯定不能围成一个矩形。

  四、若给出的4条线段可以围成矩形,则每条线段都会有两条与其垂直的线段,因此每条向量都会有两条与其垂直的向量,遍历所有向量获取与其垂直的向量数量,若不为两条那这4条线段肯定不能围成一个矩形。(向量(x1, y1)与(x2, y2)垂直 : x1 * y2 + x2 * y1 == 0)。

  若满足以上4条,给出的4条线段可以围成矩形。

  AC代码

 #include <bits/stdc++.h>
using namespace std;
int t;
set<pair<int, int> > nodeSet; //nodeSet储存所有的端点
map<pair<int, int>, vector<pair<int, int> > > edgeMap; //edgeMap[i] 储存与i相连的所有点的集合
vector<pair<int, int> > vectors; //vectors 储存每条边对应的向量
int main()
{
scanf("%d", &t); //测试数量输入
while(t--){
//清空所有容器
nodeSet.clear();
edgeMap.clear();
vectors.clear();
//每条输入的信息包括两个点(x1, y1) (x2, y2)
int x1, x2, y1, y2;
for(int i = ; i < ; i++){ //输入四条线段
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
pair<int, int> tempNode1, tempNode2, tempVectors;
// pair<int, int> tempNode1 记录第一个点 tempNode1.first记录x坐标 tempNode1.second记录y坐标
// pair<int, int> tempNode2 记录第二个点 tempNode2.first记录x坐标 tempNode2.second记录y坐标
// pair<int, int> tempVectors 记录当前线段对应的向量 tempVectors.first记录x轴位移量 tempVectors.second记录y轴位移量
tempNode1.first = x1;
tempNode1.second = y1;
nodeSet.insert(tempNode1); //nodeSet中加入tempNode1
tempNode2.first = x2;
tempNode2.second = y2;
nodeSet.insert(tempNode2); //nodeSet中加入tempNode2
edgeMap[tempNode1].push_back(tempNode2); //tempNode1的连通顶点集中加入tempNode2
edgeMap[tempNode2].push_back(tempNode1); //tempNode2的连通顶点集中加入tempNode1
tempVectors.first = x2 - x1; //计算x轴位移量
tempVectors.second = y2 - y1; //计算y轴位移量
vectors.push_back(tempVectors); //向量集vectors中加入tempVectors
}
if(nodeSet.size() != ){ //判断端点是否为4个
printf("NO\n");
continue;
}
bool isRectangle = true;
for(auto i : nodeSet){ //判断每个端点的度是否为2
if(edgeMap[i].size() != ){
printf("NO\n");
isRectangle = false;
break;
//goto here; 保持气节不要用goto goto是程序的敌人 我一开始用的goto 虽然也AC了不过我改过自新,回头是岸
}
}
if(!isRectangle)
continue;
isRectangle = true;
int cnt;
for(auto i : vectors){ //判断每条向量是否有一条向量与其平行且相等
cnt = ;
for(auto j : vectors){
if(i == j || (i.first == -j.first && i.second == -j.second)){
cnt++;
}
}
if(cnt != ){ //加上本身一共两个
printf("NO\n");
isRectangle = false;
break;
//goto here;
}
}
if(!isRectangle)
continue;
isRectangle = true;
for(auto i : vectors){ //判断每条向量是否有两个与其垂直的向量
cnt = ;
for(auto j : vectors){
if(i.first * j.second + j.first * i.second == ){
cnt++;
}
}
if(cnt != ){
printf("NO\n");
isRectangle = false;
break;
//goto here;
}
}
if(!isRectangle)
continue;
printf("YES\n");
//here:;
}
return ;
}

HihoCoder - 1040 矩形判断的更多相关文章

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

    #1040 : 矩形判断 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 给出平面上4条线段,判断这4条线段是否恰好围成一个面积大于0的矩形. 输入 输入第一行是一个整数T ...

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

    http://hihocoder.com/problemset/problem/1040 首先判断四条线段是否相交,给出八个点,如果有一些点重合,并且不同坐标的点只有4个的话,表示可以构成四边形. 然 ...

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

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

  4. hihoCoder 1040 矩阵判断 最详细的解题报告

    题目来源:矩阵判断 解题思路: 1.判断矩阵的4个点是否相连,一共输入8个点,只要判断是否4个点是否都经过2遍: 2.判断矩阵中任意一条边与其他边之间要么平行,要么垂直.设A(x1,y1),B(x2, ...

  5. [hihoCoder]矩形判断

    #1040 : 矩形判断 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 给出平面上4条线段,判断这4条线段是否恰好围成一个面积大于0的矩形. 输入 输入第一行是一个整数T ...

  6. hihocoder 1040(矩形判断)

    题目链接:传送门 题目大意:给你四条线段,判断能否围成一个面积大于0的矩形,能输出YES,不能输出NO 题目思路:    合法的四条线段应该满足 1.应该必须有四个不同的点 2.线段斜率分为两组,组内 ...

  7. 容斥 或者 单调栈 hihocoder #1476 : 矩形计数 和 G. Snake Rana 2017 ACM Arabella Collegiate Programming Contest

    先说一个简单的题目(题目大意自己看去,反正中文):hihocoder上的:http://hihocoder.com/problemset/problem/1476 然后因为这个n和m的矩阵范围是100 ...

  8. [bzoj2517]矩形覆盖

    Description 给定一个$l\;\times\;w$的矩形,和$n$个圆,求最小的$k$使得每个圆的半径$\;\times\;k$后,能覆盖整个矩形. Input 第一行一个整数$T$,表示数 ...

  9. POJ 1410 Intersection (线段和矩形相交)

    题目: Description You are to write a program that has to decide whether a given line segment intersect ...

随机推荐

  1. Ansible基本命令

    Ansible安装完成之后就自带很多命令,其中较常用的有7个: ansible ansible-doc ansible-galaxy ansible-init ansible-playbook ans ...

  2. ReportMachine OCX

    http://rmachine.haotui.com/thread-55-1-1.html 偏高偏低提示 [IF( [RMDBDataSet1."abnormalIndicator" ...

  3. 程序员MAC必备

    排名不分先后 • iTerm 2 终端工具(建议配合oh-my-zsh使用) • Shadowsocks     ***工具 (可用于FQ) • Foxmail 邮箱工具 (适用于企业邮箱登陆) • ...

  4. 玩了下STM8单片机

    偶然的机会,发现STM8真是又便宜又好用啊,哈哈! 买了一个STM8S103F3的小板子,再加一个ST-Link调试器,总共才35块钱!对于我们这种玩习惯了动辄上千上万的FPGA开发板的人来说,就是白 ...

  5. Node.js-Usage & Example

    Usage# node [options] [v8 options] [script.js | -e "script"] [arguments] Please see the Co ...

  6. Django:上传文件或者图片时request.FILES的值为空

    在form表单中加上属性 enctype="multipart/form-data"

  7. CentOS IPv6设置

    1)/etc/sysconfig/network  打开/关闭网络配置 添加: NETWORKING_IPV6=yes  打开IPv6 IPV6_AUTOCONF=no        如果不喜欢自动获 ...

  8. Spark MLlib中的OneHot哑变量实践

    在机器学习中,线性回归和逻辑回归算是最基础入门的算法,很多书籍都把他们作为第一个入门算法进行介绍.除了本身的公式之外,逻辑回归和线性回归还有一些必须要了解的内容.一个很常用的知识点就是虚拟变量(也叫做 ...

  9. Android应用安全防护和逆向分析 ——apk混淆成其他语言代码

    现在很多人对于app的安全是越来越重视了,尤其是金融相关的行业,对于app的防范可是下足了功夫.各种加固,各种加密算法,层出不穷.我个人觉得,在安全技术这块,没有绝对安全的.也许今天这个技术起到了防范 ...

  10. Linux零碎知识

    ln -s用法: 创建软连接,命令如下: ln -s / /home/good/linkname ln的链接分软链接和硬链接两种: .软链接就是:“ln –s 源文件 目标文件”,只会在选定的位置上生 ...