*HDU 1086 计算几何
You can Solve a Geometry Problem too
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 10259 Accepted Submission(s): 5074
geometry(几何)problems were designed in the ACM/ICPC. And now, I also
prepare a geometry problem for this final exam. According to the
experience of many ACMers, geometry problems are always much trouble,
but this problem is very easy, after all we are now attending an exam,
not a contest :)
Give you N (1<=N<=100) segments(线段), please
output the number of all intersections(交点). You should count repeatedly
if M (M>2) segments intersect at the same point.
Note:
You can assume that two segments would not intersect at more than one point.
contains multiple test cases. Each test case contains a integer N
(1=N<=100) in a line first, and then N lines follow. Each line
describes one segment with four float values x1, y1, x2, y2 which are
coordinates of the segment’s ending.
A test case starting with 0 terminates the input and this test case is not to be processed.
0
第1 步:快速排斥试验,如果分别以P1P2 ,P3P4 为对角线做矩形,而这两个矩形不相交,则这两条线段肯定不相交,如下左图;即使两个矩形相交,这两条线段也不一定相交,如下右图,这时再用第2 步判断;
表示成语句,即两个矩形相交当且仅当下列式子为真:
(max(x1,x2)≥min(x3,x4))&& (max(x3,x4)≥min(x1,x2)) &&(max(y1,y2)≥min(y3,y4))&&(max(y3,y4)≥min(y1,y2))
两个矩形相交必须在两个方向上都相交,式子的前半部分判断在x 方向上是否相交,后半部分判断在y 方向上是否相交。
第2 步:确定每条线段是否“跨立”另一条线段所在的直线。
跨立:如果点P1 处于直线P3P4的一边,而P2处于该直线的另一边,则我们说线段p1p2跨立直线P3P4,如果P1 或P2 在直线P3P4 上,也算跨立。
两条线段相交当且仅当它们能够通过第1 步的快速排斥试验,并且每一条线段都跨立另一条线段所在的直线。
具体第2 步的实现,只要用叉积去做就可以了,即只要判断矢量p1p3和p1p4是否在p1p2的两边相对的位置上,如果这样,则线段p1p2跨立直线P3P4。也即检查叉积(P3-P1)×(P2-P1)与(P4-P1)×(P2-P1)的符号是否相同,相同则不跨立,线段也就不相交,否则相交。
当然也有一些特殊情况需要处理,如任何一个叉积为0,则P3 或P4 在直线P1P2 上,又因为通过了快速排斥试验,所以下图左边的情况是不可能出现的,只会出现右边的两种情况。当然,还会出现一条或两条线段的长度为0,如果两条线段的长度都是0,则只要通过快速排斥试验就能确定;如果仅有一条线段的长度为0,如p3p4的长度为0,则线段相交当且仅当叉积(P3-P1)×(P2-P1)。
有关于叉积的概念:
矢量的矢量积(叉乘、叉积)
① 矢量积的一般含义:两个矢量a 和b 的矢量积是一个矢量,记作a×b,其模等于由a 和b作成的平行四边形的面积,方向与平行四边形所在平面垂直,当站在这个方向观察时,a 逆时针转过一个小于π的角到达b 的方向。这个方向也可以用物理上的右手螺旋定则判断:右手四指弯向由A 转到B 的方向(转过的角小于π),拇指指向的就是矢量积的方向。如下图(左)。
② 我们给出叉积的等价而更有用的定义,把叉积定义为一个矩阵的行列式:
如上右图,如果 p1 × p2 为正数,则相对原点(0,0)来说, p1 在p 2 的顺时针方向; 如果p 1 × p2为负数,则p 1 在p 2 的逆时针方向。如果p 1× p2 =0,则p 1和p 2 模相等且共线,方向相同或相反。
③ 给定两个矢量:P0P1和P0P2,对它们的公共端点P0来说,判断P0P1是否在P0P2的顺时针方向。
方法:如上图,把0 p 作为原点,得出向量P1’=P1-P0 和P2’=P2-P0,因此,这两个向量的叉积为: 如果该叉积为正,则P0P1在P0P2的顺时针方向,如果为负,则P0P1在P0P2的逆时针方向。如果等于0,则P0,P1,P2三点共线。
④ 讨论另一个重要问题:确定连续线段是向左转还是向右转,如下图,即两条连续线段P0P1
和P1P2在点P1 是向左转还是向右转。也即∠P1P0P2的转向。
方法:叉积,同上。
这道题还要注意一点:


#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
double nodx1[],nody1[],nodx2[],nody2[];
int n;
int main()
{
while(scanf("%d",&n)&&n)
{
for(int i=;i<n;i++)
scanf("%lf%lf%lf%lf",&nodx1[i],&nody1[i],&nodx2[i],&nody2[i]);
double x1,y1,x2,y2;
int ans=;
for(int i=;i<n-;i++)
for(int j=i+;j<n;j++)
{
if(!((min(nodx1[i],nodx2[i])<=max(nodx1[j],nodx2[j]))
&&(max(nody1[i],nody2[i])>=min(nody1[j],nody2[j]))
&&(min(nodx1[j],nodx2[j])<=max(nodx1[i],nodx2[i]))
&&(max(nody1[j],nody2[j])>=min(nody1[i],nody2[i]))))
continue; //快速排斥
x1=nodx2[i]-nodx1[i];y1=nody2[i]-nody1[i];
x2=nodx2[j]-nodx1[i];y2=nody2[j]-nody1[i];
double tem1=x2*y1-x1*y2;
x2=nodx1[j]-nodx1[i];y2=nody1[j]-nody1[i];
double tem2=x2*y1-x1*y2;
x1=nodx2[j]-nodx1[j];y1=nody2[j]-nody1[j];
x2=nodx2[i]-nodx1[j];y2=nody2[i]-nody1[j];
double tem3=x2*y1-x1*y2;
x2=nodx1[i]-nodx1[j];y2=nody1[i]-nody1[j];
double tem4=x2*y1-x1*y2;
if(tem1*tem2<=&&tem3*tem4<=) ans++;
}
printf("%d\n",ans);
}
return ;
}
*HDU 1086 计算几何的更多相关文章
- hdu 1086(计算几何入门题——计算线段交点个数)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=1086 You can Solve a Geometry Problem too Time Limit: 2 ...
- hdu 1086:You can Solve a Geometry Problem too(计算几何,判断两线段相交,水题)
You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/3 ...
- hdu 2108:Shape of HDU(计算几何,判断多边形是否是凸多边形,水题)
Shape of HDU Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- HDU 2202 计算几何
最大三角形 Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- *HDU 2108 计算几何
Shape of HDU Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- HDU 5784 (计算几何)
Problem How Many Triangles (HDU 5784) 题目大意 给定平面上的n个点(n<2000),询问可以组成多少个锐角三角形. 解题分析 直接统计锐角三角形较困难,考虑 ...
- hdu 4720 计算几何简单题
昨天用vim练了一道大水题,今天特地找了道稍难一点的题.不过也不是很难,简单的计算几何而已.练习用vim编码,用gdb调试,结果居然1A了,没调试...囧... 做法很简单,无非就是两种情况:①三个巫 ...
- HDU 1086:You can Solve a Geometry Problem too
pid=1086">You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others) Mem ...
- HDU 6205[计算几何,JAVA]
题目链接[http://acm.hdu.edu.cn/showproblem.php?pid=6206] 题意: 给出不共线的三个点,和一个点(x,y),然后判断(x,y)在不在这三个点组成的圆外. ...
随机推荐
- 安装yii2时出错 Invalid Parameter – yii\base\InvalidParamException
最近composer安装yii2的时候页面报了这个错,应该是bower的前端资源位置改变的缘故! Invalid Parameter – yii\base\InvalidParamException ...
- 使用excel计算指数平滑和移动平均
指数平滑法 原数数据如下: 点击数据——数据分析 选择指数平滑 最一次平滑 由于我们选择的区域是B1:B22,第一个单元格“钢产量”,被当做标志,所以我们应该勾选标志.当我们勾选了标志后,列中的第 ...
- PHP连接mysql数据库,并将取出的数据以json的格式输出
<?php error_reporting(E_ALL || ~E_NOTICE); header("Access-Control-Allow-Origin:*");//此处 ...
- 使用php+swoole对client数据实时更新(上)
如果想对一个列表做实时的更新,传统的做法是采用轮询的方式.以web为例,通过Ajax定时请求服务端然后获取数据显示在页面.这种方式实现简单,缺点就是浪费资源. HTTP1.1新增加了对websocke ...
- js判断本地是否安装app
var ua = navigator.userAgent.toLowerCase(); 1.判断是否是微信 function isWeixinBrowser() { return (/micromes ...
- 探索 OpenStack 之(7):Neutron 深入探索之 Open vSwitch (OVS) + GRE 之 Neutron节点篇
0. 测试环境 硬件环境:还是使用四节点OpenStack部署环境,参见 http://www.cnblogs.com/sammyliu/p/4190843.html OpenStack配置: ten ...
- php实验四
实验四 1.创建一个Person类,Person中包含三个属性name,age,wealth,分别设置为public,private,protected,再定义Person类的子类Student. 2 ...
- asp.net中membership使用oracle数据库(二)
需要安装的东西都准备好了,继续生成后台表.过程.函数.触发器等.ps/sql中 @@E:\oracle\product\11.2.0\client_1\ASP.NET\SQL\InstallAllOr ...
- POJ 3155 Hard Life(最大密度子图)
裸题.输入一个无向图,输出最大密度子图(输出子图结点数和升序编号). 看了<最小割模型在信息学竞赛中的应用——胡伯涛>的一部分,感觉01分数规划问题又是个大坑.暂时还看不懂. 参考http ...
- .NET 反射概述
反射 反射提供了封装程序集.模块和类型的对象(Type 类型).可以使用反射动态创建类型的实例,将类型绑定到现有对象,或从现有对象获取类型并调用其方法或访问其字段和属性.如果代码中使用了属性 ...