当前位置: 首页 > news >正文

HDU 1086 You can Solve a Geometry Problem too

算法简单说明:  
 
首先判断以两条线段为对角线的矩形是否相交,如果不相交两条线段肯定也不相交。

(所谓以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<stdio.h>
#include
<stdlib.h>
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<p2.x?p1.x:p2.x;
if( p.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

相关文章:

  • [Notes]python argparse模块
  • 最新50个不错的免费PSD素材下载(下篇)
  • Hibernate(五)之一对多多对一映射关系
  • Windows 7的预备知识系列之二:认识Windows 7中的窗口
  • [jquery]this触发自身click事件,当前控件向上滑出
  • 转:获取网页URL地址及参数等的两种方法(js和C#)
  • 前后端数据交互的方式有哪些?
  • MongoDB.Mastering_Find()
  • windows7编程-任务栏进度条
  • CRC8算法DELPHI源码
  • NHibernate 快速入门(四)使用 HQL 查询数据
  • HashMap底层实现原理
  • Location Aware DNS Server-----项目部署说明
  • pyqt 调用QT设计师创建的对话框
  • 艾伟_转载:下载文件时根据MIME类型自动判断保存文件的扩展名
  • [LeetCode] Wiggle Sort
  • emacs初体验
  • java多线程
  • Java应用性能调优
  • Python爬虫--- 1.3 BS4库的解析器
  • vue脚手架vue-cli
  • weex踩坑之旅第一弹 ~ 搭建具有入口文件的weex脚手架
  • 翻译--Thinking in React
  • 浮现式设计
  • 更好理解的面向对象的Javascript 1 —— 动态类型和多态
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 使用agvtool更改app version/build
  • 在Mac OS X上安装 Ruby运行环境
  • MiKTeX could not find the script engine ‘perl.exe‘ which is required to execute ‘latexmk‘.
  • 【干货分享】dos命令大全
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • 翻译 | The Principles of OOD 面向对象设计原则
  • ​LeetCode解法汇总2670. 找出不同元素数目差数组
  • ​sqlite3 --- SQLite 数据库 DB-API 2.0 接口模块​
  • # Python csv、xlsx、json、二进制(MP3) 文件读写基本使用
  • #stm32驱动外设模块总结w5500模块
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • (+3)1.3敏捷宣言与敏捷过程的特点
  • (10)STL算法之搜索(二) 二分查找
  • (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  • (2)关于RabbitMq 的 Topic Exchange 主题交换机
  • (2015)JS ES6 必知的十个 特性
  • (4)STL算法之比较
  • (C++17) optional的使用
  • (DFS + 剪枝)【洛谷P1731】 [NOI1999] 生日蛋糕
  • (WSI分类)WSI分类文献小综述 2024
  • (二)fiber的基本认识
  • (附源码)spring boot建达集团公司平台 毕业设计 141538
  • (附源码)springboot学生选课系统 毕业设计 612555
  • (转)jdk与jre的区别
  • (转)ORM
  • .halo勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .NET 回调、接口回调、 委托
  • .NETCORE 开发登录接口MFA谷歌多因子身份验证
  • .net分布式压力测试工具(Beetle.DT)