*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)在不在这三个点组成的圆外. ...
随机推荐
- WampServer数据库导入sql文件
WampServer中MySQL如何导入sql文件: http://jingyan.baidu.com/article/3c343ff7f9c7940d377963c0.html
- 【Alpha】Daily Scrum Meeting第十次
一.本次Daily Scrum Meeting主要内容 每个人学习情况 测试的任务的安排 Alpha版本展示的具体内容 二.任务安排 学号尾数 昨天做的任务 今天做的任务 任务用时 612 完成将计时 ...
- RobotFrameWork(三)数据类型
1.1 数字变量 执行结果: 1.2 布尔变量和None/null 执行结果: 1.3 字符串.元组.list和字典 执行结果: 1.4 space和empty 执行结果:
- quartz集群报错but has failed to stop it. This is very likely to create a memory leak.
quartz集群报错but has failed to stop it. This is very likely to create a memory leak. 在一台配置1核2G内存的阿里云服务器 ...
- 此地址使用了一个通常用于网络浏览以外的端口。出于安全原因,Firefox 取消了该请求
FirFox打开80以外的端口,会弹出以下提示: “此地址使用了一个通常用于网络浏览以外的端口.出于安全原因,Firefox 取消了该请求.”. 解决方法如下: 在Firefox地址栏输入about: ...
- objccn-图片格式
图像格式存储:位图和矢量图像.位图把值存在阵列中,矢量格式存储的是绘图图像的指令.还有混合格式PostScript能够排布字母甚至位图,使其成为了一个非常灵活的方式.衍生格式pdf. xcdoe6已经 ...
- NavigationController
前面的一篇文章<iOS开发16:使用Navigation Controller切换视图>中的小例子在运行时,屏幕上方出现的工具栏就是Navigation Bar,而所谓UINavigati ...
- [Android Pro] listView和GridView的item设置的高度和宽度不起作用
referece to : http://blog.csdn.net/beibeixiao/article/details/9032569 1. 在Android开发中会发现,有时listVi ...
- .NET 获取客户端的操作系统版本、浏览器版本和IP地址
我们在使用.NET做网站的时候,很多情况下需要需要知道客户端的操作系统版本和浏览器版本,怎样获取客户端的操作系统和浏览器版本呢?我们可以通过分析UserAgent来获取. .NET 获取客户端的操作系 ...
- STM32F407Discovery开发板使用环境搭建
差不多4年前买了STM32F407Discovery这块开发板,也用它作为我的毕业设计的一部分,今晚整理一下东西,觉得这么不错的东西应该再次利用起来,做个智能家居系统的一部分什么的也不错,于是,记录一 ...