You can Solve a Geometry Problem too (hdu1086)几何,判断两线段相交
You can Solve a Geometry Problem too
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6837 Accepted Submission(s):
3303
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 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.
one line one case.
若是判断直线和线段是否有交点,把on_segment去掉就可以了
判断两线段是否相交:
我们分两步确定两条线段是否相交:
(1)快速排斥试验
设以线段 P1P2 为对角线的矩形为R, 设以线段 Q1Q2 为对角线的矩形为T,如果R和T不相交,显然两线段不会相交。
(2)跨立试验
如果两线段相交,则两线段必然相互跨立对方。若P1P2跨立Q1Q2 ,则矢量 ( P1 - Q1 ) 和( P2 - Q1 )位于矢量( Q2 - Q1 ) 的两侧,即( P1 - Q1 ) × ( Q2 - Q1 ) * ( P2 - Q1 ) × ( Q2 - Q1 ) < 0。上式可改写成( P1 - Q1 ) × ( Q2 - Q1 ) * ( Q2 - Q1 ) × ( P2 - Q1 ) > 0。当 ( P1 - Q1 ) × ( Q2 - Q1 ) = 0 时,说明 ( P1 - Q1 ) 和 ( Q2 - Q1 )共线,但是因为已经通过快速排斥试验,所以 P1 一定在线段 Q1Q2上;同理,( Q2 - Q1 ) ×(P2 - Q1 ) = 0 说明 P2 一定在线段 Q1Q2上。所以判断P1P2跨立Q1Q2的依据是:( P1 - Q1 ) × ( Q2 - Q1 ) * ( Q2 - Q1 ) × ( P2 - Q1 ) >= 0。同理判断Q1Q2跨立P1P2的依据是:( Q1 - P1 ) × ( P2 - P1 ) * ( P2 - P1 ) × ( Q2 - P1 ) >= 0。具体情况如下图所示:

在相同的原理下,对此算法的具体的实现细节可能会与此有所不同,除了这种过程外,大家也可以参考《算法导论》上的实现。
关于计算几何算法概述网站 http://dev.gameres.com/Program/Abstract/Geometry.htm 一个挺好的网站
#include<stdio.h>//判断线段相交模版 struct point
{
double x,y;
}; double direction( point p1,point p2,point p )
{
//叉乘符号,向量a(x1,y1)×向量b(x2,y2)=x1*y2-x2*y1;
return ( p1.x -p.x )*( p2.y-p.y) - ( p2.x -p.x )*( p1.y-p.y) ;
} int on_segment( point p1,point p2 ,point p )
{
double max=p1.x > p2.x ? p1.x : p2.x ;
double min =p1.x < p2.x ? p1.x : p2.x ; if( p.x >=min && p.x <=max )
return ;
else
return ;
} int segments_intersert( point p1,point p2,point p3,point p4 )
{
double d1,d2,d3,d4;
//判断p3和p4是否在p1和p2两侧
d1 = direction ( p1,p2,p3 );
d2 = direction ( p1,p2,p4 );
//判断p1和p2是否在p3和p4两侧
d3 = direction ( p3,p4,p1 );
d4 = direction ( p3,p4,p2 );
if( d1*d2< && d3*d4< )//在两侧,说明p1p2和p3p4相交
return ;
else if( d1== && on_segment( p1,p2,p3 ) )
return ;
else if( d2== && on_segment( p1,p2,p4 ) )
return ;
else if( d3== && on_segment( p3,p4,p1 ) )
return ;
else if( d4== && on_segment( p3,p4,p2 ) )
return ; return ;
} int main()
{
int n,i,j,num;
point begin[],end[]; //结构体数组 while(scanf("%d",&n)&&n!= )
{
num=;
for(i=;i<n;i++)
{
scanf("%lf%lf%lf%lf",&begin[i].x ,&begin[i].y ,&end[i].x ,&end[i].y );
}
for(i=;i<n;i++)//线段两两比较
{
for(j=i+;j<n;j++)
{
if( segments_intersert( begin[i],end[i],begin[j],end[j] ) )
num++;
}
}
printf("%d\n",num);
}
return ;
}
几何,哥哥要征服你,fighting!
You can Solve a Geometry Problem too (hdu1086)几何,判断两线段相交的更多相关文章
- 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 ...
- (叉积,线段判交)HDU1086 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 ...
- HDU1086 You can Solve a Geometry Problem too(计算几何)
You can Solve a Geometry Problem too Time Limit: 2000/1000 M ...
- HDU1086You 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 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 step 7.1.2)You can Solve a Geometry Problem too(乞讨n条线段,相交两者之间的段数)
称号: You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/ ...
- 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 ...
- 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 ...
- You can Solve a Geometry Problem too(线段求交)
http://acm.hdu.edu.cn/showproblem.php?pid=1086 You can Solve a Geometry Problem too Time Limit: 2000 ...
随机推荐
- 多个文本框录入,使用回车键替找Tab键
为了快速把form的所有文框输入完毕,我们不必使用鼠标去focus文本框. 在html页中放几个文本框: <div class="DivInput"> <div& ...
- JSOI2010 缓存交换
题目链接:戳我 考虑一个贪心--就是每次我们都选择队列里面之后最晚加入的元素弹出. 维护一个nxt数组就行了. 特判一下之后不会再加入的元素. 代码如下: #include<iostream&g ...
- MariaDB 存储过程与函数(10)
MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可MariaDB的目的是完全兼容MySQL,包括API和命令行,MySQL由于现在闭源了,而能轻松成为MySQ ...
- C#6.0语言规范(六) 转换
转换能够被视为是一个特定类型的表达式.转换可能会导致给定类型的表达式被视为具有不同的类型,或者它可能导致没有类型的表达式获取类型.转换可以是隐式或显式的,这决定了是否需要显式转换.例如,从类型int到 ...
- Swift 里 Set(二)概览
类图  Set 是一个结构体,持有另一个结构体_Variant. 最终所有的元素存储在一个叫做__RawSetStorage的类里. 内存布局  结构体分配在栈上,和__RawSetStorage ...
- postgresql-pg_prewarm数据预加载。
pg_prewarm数据预加载. http://francs3.blog.163.com/blog/static/405767272014419114519709/ https://www.kan ...
- 使用webpack和react搭建项目
看了N多博客,日志,一边迷茫一边摸索.本文记录流程.我怕自己忘了...并且修复了博客园首页推荐那个日志中遇到的bug 1.webstorm新建一个空白项目,比如webpack_demo 2.因为要用r ...
- Oracle RAC 环境下的连接管理(转) --- 防止原文连接失效
崔华老师的文章!!! 这篇文章详细介绍了Oracle RAC环境下的连接管理,分别介绍了什么是 Connect Time Load Balancing.Runtime Connection Load ...
- Bash数组
1. 数组申明 declare -a array 2. 数组赋值 #法1 array=(var1 var2 var3 ... varN) #法2 array=([]=var1 []=var2 []=v ...
- dockerfile简述
作用 Dockerfile的内容是一坨可以执行的代码(或者说是指令)(docker的DSL),这些代码使得创建镜像的操作可以复用以及自动化. 指令格式 Dockerfile的指令格式很简单: INST ...