博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 1086 You can Solve a Geometry Problem too
阅读量:6509 次
发布时间:2019-06-24

本文共 2139 字,大约阅读时间需要 7 分钟。

算法简单说明:  

  首先判断以两条线段为对角线的矩形是否相交,如果不相交两条线段肯定也不相交。

(所谓以a1b2为对角钱的矩形就是以两边长为|a1.x – b2.x||a1.y – b2.y|以及a1b2为对角线的矩形)。

如果相交的话,利用矢量叉乘判断两条线段是否相互跨越,如果相互跨越显然就相交,反之则不相交。算法不难,但是一些特殊情况需要考虑到,比如两条相段共线且在断点处相交。下面的代码经过测试了,应该没有bug,如果你真的发现了bug请告诉我:)  

   
  /********************************************************   * *  
    * 返回(P1-P0)*(P2-P0)的叉积。 *  
    *
若结果为正,则<P0,P1><P0,P2>的顺时针方向; *  
    *
若为0<P0,P1><P0,P2>共线; *  
    *
若为负则<P0,P1><P0,P2>的在逆时针方向; *  
    *
可以根据这个函数确定两条线段在交点处的转向, *  
    *
比如确定p0p1p1p2p1处是左转还是右转,只要     *  
    *              
(p2-p0)*(p1-p0),若<0则左转,>0则右转,=0   *  
    *              
共线                                                                                     *  
    * *  
  \********************************************************/  
   
  float   multiply(TPoint   p1,TPoint   p2,TPoint   p0)  
  {  
  return((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y));  
  }  

#include
#include
typedef struct T {
double x,y; } point; double judge( point p1,point p2, point p )//判断点是否在直线的两边 {
return ( p1.x-p.x )*( p2.y-p.y )-( p2.x-p.x )*( p1.y-p.y ); } bool on_segments( point p1, point p2, point p )//判断端点是不是在直线上 {
double max=p1.x>p2.x?p1.x:p2.x;//找出直线的左右端点的范围 double min=p1.x
=min&&p.x<=max ) return true; else return false; } bool segments( point p1,point p2,point q1,point q2 ) {
double d1=judge( p1, p2, q1 ); double d2=judge( p1, p2, q2 ); double d3=judge( q1, q2, p1 ); double d4=judge( q1, q2 ,p2 ); if( d1*d2<0&&d3*d4<0 ) return true; if( d1==0 && on_segments( p1,p2,q1 ) ) return true;//d为0是平行的情况,这是我们就要考虑是不是端点在直线上 if( d2==0 && on_segments( p1,p2,q2 ) ) return true ; if( d3==0 && on_segments( q1,q2,p1 ) ) return true; if( d4==0 && on_segments( q1,q2,p2 ) ) return true; return false; } int main() {
point start[124],end[124]; int n; while( scanf("%d",&n),n ) {
int sum=0; for( int i=1; i<=n; i++ ) {
scanf( "%lf%lf%lf%lf",&start[i].x,&start[i].y,&end[i].x,&end[i].y ); } for( int i=1; i<=n; i++ ) for( int j=i+1; j<=n; j++ ) {
if( segments( start[i],end[i],start[j],end[j] ) ) sum++; } printf( "%d\n",sum ); } return 0; }

  

转载于:https://www.cnblogs.com/bo-tao/archive/2011/08/16/2140805.html

你可能感兴趣的文章
java 设计模式之桥梁模式
查看>>
[Java] 图说 注解
查看>>
js实现天小时分钟秒倒计时
查看>>
浅谈Tomcat服务器优化方法
查看>>
面向对象访问修饰符
查看>>
安装oracle出现环境不满足最低要求
查看>>
Java并发编程(一)并发特性
查看>>
css3 渐变实例2径向渐变
查看>>
Python通用编程 - 第四章:字符编码
查看>>
好程序员java教程分享+号与append的效率问题
查看>>
滚动字幕标记<marquee></marquee>
查看>>
Hadoop2搭建Federation+HA
查看>>
bzoj 1066: [SCOI2007] 蜥蜴
查看>>
JQ和Js获取span标签的内容
查看>>
计算机网络的现实应用
查看>>
oracle笔记
查看>>
jQuery学习笔记(二)
查看>>
线性回归
查看>>
操作系统概述
查看>>
java研发工作组环境架设
查看>>