Pick-up sticks(判断两条线段是否相交)
| Time Limit: 3000MS | Memory Limit: 65536K | |
| Total Submissions: 8351 | Accepted: 3068 |
Description
Input
Output
The picture to the right below illustrates the first case from input.
Sample Input
5
1 1 4 2
2 3 3 1
1 -2.0 8 4
1 4 8 2
3 3 6 -2.0
3
0 0 1 1
1 0 2 1
2 0 3 1
0
Sample Output
Top sticks: 2, 4, 5.
Top sticks: 1, 2, 3. 题意:给n个木条,每条线段元素包含四个数,分别是其端点的横纵坐标,n个木条依次按先后顺序扔出,问放在最上面的木条的序号; 思路:判断两条线段相交问题,判断每个木条与它后面的木条是否相交,若相交,则当前木条肯定不是最上面的,用标记数组进行标记,最后遍历一遍输出序号就可以了;

#include<stdio.h>
#include<algorithm>
#include<math.h>
using namespace std;
const int maxn = ; struct point
{
double x,y;
point(){}
point(double a,double b):x(a),y(b) {}
friend point operator - (const point &a,const point &b)
{
return point(a.x-b.x,a.y-b.y);
}
friend double operator ^(const point &a,const point &b)
{
return a.x*b.y-a.y*b.x;
}
friend double operator *(const point &a, const point &b)
{
return a.x*b.x + a.y*b.y;
}
}; struct line
{
point a;
point b;
int flag;
line (){}
line (point x, point y):a(x),b(y) {}
}L[maxn]; const double eps = 1e-;
int cmp(double x)
{
if(fabs(x) < eps)
return ;
if(x > )
return ;
return -;
} bool inter(line L1, line L2)//判断两条线段是否相交
{
return
//快速排斥实验
max(L1.a.x,L1.b.x) >= min(L2.a.x,L2.b.x) &&
max(L2.a.x,L2.b.x) >= min(L1.a.x,L1.b.x) &&
max(L1.a.y,L1.b.y) >= min(L2.a.y,L2.b.y) &&
max(L2.a.y,L2.b.y) >= min(L1.a.y,L1.b.y) &&
//跨立实验
cmp((L2.a-L1.a)^(L1.b-L1.a))*cmp((L2.b-L1.a)^(L1.b-L1.a)) <= &&
cmp((L1.a-L2.a)^(L2.b-L2.a))*cmp((L1.b-L2.a)^(L2.b-L2.a)) <= ;
} int main()
{
int n;
while(~scanf("%d",&n) && n)
{
double x1,y1,x2,y2;
struct point p1,p2;
for(int i = ; i < n; i++)
{
scanf("%lf %lf %lf %lf",&x1,&y1,&x2,&y2);
p1.x = x1;
p1.y = y1;
p2.x = x2;
p2.y = y2;
L[i].a = p1;
L[i].b = p2;
L[i].flag = ;
} for(int i = ; i < n-; i++)
{
for(int j = i+; j < n; j++)
{
if(inter(L[i],L[j]))//如果第i条线段与第j条线段(i<j)相交,第i条线段显然不可能是最上边的;
{
L[i].flag = ;
break;
}
}
} printf("Top sticks:");
int ok = ;
for(int i = ; i < n; i++)
{
if(L[i].flag == )
{
if(ok == )
{
printf(" %d",i+);
ok = ;
}
else printf(", %d",i+);
}
}
printf(".\n"); }
return ;
}
判断两条线段是否相交问题:
(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 。
当快速排斥实验和跨立实验都满足时,才说明两天线段相交;
Pick-up sticks(判断两条线段是否相交)的更多相关文章
- [CSharpTips]判断两条线段是否相交
判断两条线段是否相交 主要用到了通过向量积的正负判断两个向量位置关系 向量a×向量b(×为向量叉乘),若结果小于0,表示向量b在向量a的顺时针方向:若结果大于0,表示向量b在向量a的逆时针方向:若等于 ...
- c# 判断两条线段是否相交(判断地图多边形是否相交)
private void button1_Click(object sender, EventArgs e) { //var result = intersect3(point1, point2, p ...
- 计算几何--判断两条线段相交--poj 2653
Pick-up sticks Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 8862 Accepted: 3262 De ...
- 求两条线段交点zz
"求线段交点"是一种非常基础的几何计算, 在很多游戏中都会被使用到. 下面我就现学现卖的把最近才学会的一些"求线段交点"的算法说一说, 希望对大家有所帮助. 本 ...
- 平面内,线与线 两条线找交点 两条线段的位置关系(相交)判定与交点求解 C#
个人亲自编写.测试,可以正常使用 道理看原文,这里不多说 网上找到的几篇基本都不能用的 C#代码 bool Equal(float f1, float f2) { return (Math ...
- 两条线段求交点+叉积求面积 poj 1408
题目链接:https://vjudge.net/problem/POJ-1408 题目是叫我们求出所有四边形里最大的那个的面积. 思路:因为这里只给了我们正方形四条边上的点,所以我们要先计算横竖线段两 ...
- The 2015 China Collegiate Programming Contest D.Pick The Sticks hdu 5543
Pick The Sticks Time Limit: 15000/10000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others ...
- 判断线段和直线相交 POJ 3304
// 判断线段和直线相交 POJ 3304 // 思路: // 如果存在一条直线和所有线段相交,那么平移该直线一定可以经过线段上任意两个点,并且和所有线段相交. #include <cstdio ...
- 2015南阳CCPC D - Pick The Sticks dp
D - Pick The Sticks Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 无 Description The story happened lon ...
随机推荐
- Android(java)学习笔记201:网络图片浏览器的实现(ANR)
1.我们在Android下,实现使用http协议进行网络通信,请求网络数据.这里是获取网络上的图片信息,让它可以显示在手机上: 但是我们这个手机连接网络是很费时间,如果我们在主线程(UI线程)中写这个 ...
- 第九章------HAL
HAL是建立在Linux驱动之上的的程序库,他是一个应用层,它的作用保护内部私有.有一种是位于Android层次的系统运行库层,Linux中只保留与寄存器相互的代码,通过HAL进行数据的传递. 为An ...
- spring xml 空模板-applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.spr ...
- ASP.NET中如何生成图形验证码
通常生成一个图形验证码主要 有3个步骤: (1)随机产生一个长度为N的随机字符串,N的值可由开发可由开发人员自行设置.该字符串可以包含数字.字母等. (2)将随机生成的字符串创建成图片,并显示. (3 ...
- 网站分析统计JS源码分享
之前公司做了一个分析云平台,用来跟踪收集海量的用户行为的相关数据,供运营人员实时监控网站访问量,统计PV,UV,独立IP,访问时段,访问时长,热点追踪等多类信息,我用JS写了一个小插件,只需要再页面加 ...
- Weex 样式
1.盒型 width height padding padding-left padding-right padding-top padding-bottom margin margin-left m ...
- 重载,重写和super
1.重载的概念:----->在同一个类中,允许存在同名函数,但它们的参数个数或者参数类型不同即可.public static void main(String[] args){System.ou ...
- log4Net配置详解
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSe ...
- 用java写bp神经网络(三)
孔子曰,吾日三省吾身.我们如果跟程序打交道,除了一日三省吾身外,还要三日一省吾代码.看代码是否可以更简洁,更易懂,更容易扩展,更通用,算法是否可以再优化,结构是否可以再往上抽象.代码在不断的重构过程中 ...
- 【转】iOS-Core-Animation-Advanced-Techniques(一)
图层树.寄宿图以及图层几何学(一)图层的树状结构 巨妖有图层,洋葱也有图层,你有吗?我们都有图层 -- 史莱克 原文:http://www.cocoachina.com/ios/20150104/1 ...