*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)在不在这三个点组成的圆外. ...
随机推荐
- hadoop集群安装故障解决
nodemanager进程解决:http://blog.csdn.net/baiyangfu_love/article/details/13504849 编译安装:http://blog.csdn.n ...
- Python的由来
Python的由来 Python这门语言是由C开发而来. C语言: 代码编译得到 机器码 ,机器码在处理器上直接执行,每一条指令控制CPU工作 其他语言: 代码编译得到 字节码 ,虚拟机执行字节码并转 ...
- jquery----常用的函数
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Eclipse关闭XML文件验证的方法
XML的编写是否符合规范,可以通过XML Schema或DTD进行验证,但有时候电脑本来就很卡,而且XML的某些错误并未导致程序无法运行的情况下,暂时关闭XML的验证也算不错的选择. 如web.xml ...
- .NET 接口
接口 接口是一组抽象成员的集合,表示某个类或结构可以选择去实现的行为,描述的是可属于任何类或结构的一组相关功能.接口方法的实现是在实现接口的类中完成的,实现接口的类可以显式实现该接口的成员, ...
- hdu 1300 Pearls
链接:http://acm.hdu.edu.cn/showproblem.php?pid=1300 思路:用dp[i]表示前i种花费最低的情况,则有dp[i]=min(dp[i],dp[j+1]+(( ...
- Mybatis关联查询(嵌套查询)
上一篇文章介绍了基于Mybatis对数据库的增.删.改.查.这一篇介绍下关联查询(join query). 三张表:user article blog 表的存储sql文件: /* Navicat My ...
- CountDownLatch
使用的实例: @Override public <V> V get(Future<V> future) { final CountDownLatch l = new Count ...
- 第二十八篇:SOUI中自定义控件开发过程
在SOUI中已经提供了大部分常用的控件,但是内置控件不可能满足用户的所有要求,因此一个真实的应用少不得还要做一些自定义控件. 学习一个新东西,最简单的办法就是依葫芦画瓢.事实上在SOUI系统中内置控件 ...
- BZOJ 2844 albus就是要第一个出场 ——高斯消元 线性基
[题目分析] 高斯消元求线性基. 题目本身不难,但是两种维护线性基的方法引起了我的思考. void gauss(){ k=n; F(i,1,n){ F(j,i+1,n) if (a[j]>a[i ...