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 ...
随机推荐
- Java Calender 类详解
一. 如何创建 Calendar 对象 Calendar 是一个抽象类, 无法通过直接实例化得到对象. 因此, Calendar 提供了一个方法 getInstance,来获得一个Calendar ...
- Android根据字符串型的资源名获取对应资源id
有时候我们想动态的根据一个字符串资源名获得到对应的资源id,如根据不同的图片名称获得对应的图片,此时就应该考虑如何实现. 大家知道,在编译Android工程时,系统会自动生成一个静态资源类R,里面根据 ...
- underscore.js源码研究(6)
概述 很早就想研究underscore源码了,虽然underscore.js这个库有些过时了,但是我还是想学习一下库的架构,函数式编程以及常用方法的编写这些方面的内容,又恰好没什么其它要研究的了,所以 ...
- 转---单页面应用下的JS内存管理
正文从这开始- 内存问题对于后端童鞋而言可能是家常便饭,特别是C++童鞋.我在实习时做过半年的c++游戏客户端开发(也是前端开发哦),也见识了各式各样的内存问题,就说说我的第一个坑,当时做个需求,就是 ...
- python互斥锁
互斥锁 进程之间数据隔离, 但是多个进程可以共享同一块数据,比如共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的,而共享带来的是竞争,竞争带来的结果就是错乱,如下 from mu ...
- Vim实用技巧系列 - tab和空格的转换
有时候,我们会修改一些代码,而这些代码中的tab设定和我们自己的设定不一样.例如,我们自己的设定是以两个空格来代替tab,而要修改的代码则是使用tab.那么,我们应该怎样快速的将又有的tab转换为空格 ...
- (转)Python3之requests模块
原文:https://www.cnblogs.com/wang-yc/p/5623711.html Python标准库中提供了:urllib等模块以供Http请求,但是,它的 API 太渣了.它是为另 ...
- C#:ListView控件如何实现点击列表头进行排序?
using System; using System.Collections; using System.Windows.Forms; namespace Common { /// <summa ...
- Android开发艺术探索学习笔记(四)
第四章 View的工作原理 4.1初识ViewRoot和DecorView ViewRoot是连接WindowManager和DecorView的纽带,View的三大流程均是通过ViewRoot来完成 ...
- 深入了解preventDefault与stopPropagation
event.preventDefault()用法介绍(阻止默认事件) 该方法将通知 Web 浏览器不要执行与事件关联的默认动作(如果存在这样的动作).例如,如果 type 属性是 "subm ...