题意:

给出n条线段两个端点的坐标,问所有线段投影到一条直线上,如果这些所有投影至少相交于一点就输出Yes!,否则输出No!。

思路:

计算几何。这道题要思考到两点:

1:把问题转化为是否存在一条直线与每条线段都有交点。证明:若存在一条直线l和所有线段相交,作一条直线m和l垂直,则m就是题中要求的直线,所有线段投影的一个公共点即为垂足。

2:枚举两两线段的各一个端点,连一条直线,再判断剩下的线段是否都和这条直线有交点。证明:若有l和所有线段相交,则可保持l和所有线段相交,左右平移l到和某一线段交于端点停止(“移不动了”)。然后绕这个交点旋转。也是转到“转不动了”(和另一线段交于其一个端点)为止。这样就找到了一个新的l满足题意,而且经过其中两线段的端点。

判断线段与直线l是否相交的方法:

1:利用叉积的性质,判断线段的两个端点是否在直线的两边。

2:求线段所在的直线tmp,求tmp与l的交点p,由线段两端点到p的距离之和,与线段的距离比较,若相等则证明线段与直线相交。

代码:

#include<iostream>
#include<cmath>
using namespace std;
const int maxn = ;
const double eps = 1e-;
int n; struct Point
{
double x, y;
}s[maxn], e[maxn]; double mult(Point sp, Point ep, Point op)
{
return (sp.x-op.x)*(ep.y-op.y) - (ep.x-op.x)*(sp.y-op.y);
} bool findd(Point p1, Point p2)
{
if(abs(p1.x-p2.x) < eps && abs(p1.y-p2.y) < eps)
return false;
for(int i = ; i < n; i ++)
if(mult(p1, p2, s[i])*mult(p1, p2, e[i]) > eps) return false;
return true;
} int main()
{
int t, i, j;
cin >> t;
while(t --)
{
cin >> n;
for(i = ; i < n; i ++)
cin >> s[i].x >> s[i].y >> e[i].x >> e[i].y;
bool flag = false;
if(n < ) flag = true;
for(i = ; i < n && !flag; i ++)
for(j = i + ; j < n && !flag; j ++) // 枚举线段的端点。
{
if(findd(s[i], s[j])) flag = true;
else if(findd(s[i], e[j])) flag = true;
else if(findd(e[i], s[j])) flag = true;
else if(findd(e[i], e[j])) flag = true;
}
if(flag) cout << "Yes!" << endl;
else cout << "No!" << endl;
}
return ;
}

POJ3304 Segments 【线段直线相交】的更多相关文章

  1. POJ 3304 Segments (直线和线段相交判断)

    Segments Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7739   Accepted: 2316 Descript ...

  2. POJ 3304 Segments 判断直线和线段相交

    POJ 3304  Segments 题意:给定n(n<=100)条线段,问你是否存在这样的一条直线,使得所有线段投影下去后,至少都有一个交点. 思路:对于投影在所求直线上面的相交阴影,我们可以 ...

  3. POJ 3304 Segments (判断直线与线段相交)

    题目链接:POJ 3304 Problem Description Given n segments in the two dimensional space, write a program, wh ...

  4. POJ 3304 Segments(判断直线与线段是否相交)

    题目传送门:POJ 3304 Segments Description Given n segments in the two dimensional space, write a program, ...

  5. Segments POJ 3304 直线与线段是否相交

    题目大意:给出n条线段,问是否存在一条直线,使得n条线段在直线上的投影有至少一个公共点. 题目思路:如果假设成立,那么作该直线的垂线l,该垂线l与所有线段相交,且交点可为线段中的某两个交点 证明:若有 ...

  6. poj 3304线段与直线相交

    http://poj.org/problem?id=3304 Segments Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: ...

  7. 判断线段和直线相交 POJ 3304

    // 判断线段和直线相交 POJ 3304 // 思路: // 如果存在一条直线和所有线段相交,那么平移该直线一定可以经过线段上任意两个点,并且和所有线段相交. #include <cstdio ...

  8. POJ 1039 Pipe【经典线段与直线相交】

    链接: http://poj.org/problem?id=1039 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22013#probl ...

  9. URAL 1966 Cycling Roads 点在线段上、线段是否相交、并查集

    F - Cycling Roads     Description When Vova was in Shenzhen, he rented a bike and spent most of the ...

随机推荐

  1. verilog 数据格式

    基数格式(通常为无符号数)[size]'base value size常量的位数 base数制o:8 b:2 d:10 h:16 https://wenku.baidu.com/view/f63daa ...

  2. codeforces365B

    The Fibonacci Segment CodeForces - 365B You have array a1, a2, ..., an. Segment [l, r] (1 ≤ l ≤ r ≤  ...

  3. 美国运营商推送假5G图标:用户当场蒙圈了

    面对5G大潮,大家都想“争当第一”.美国运营商AT&T想出奇招,打算玩一把“障眼法”. 据外媒报道,AT&T的用户从明年开始会在手机右上角看到“5G E”的图标.当然,这并不是他们的手 ...

  4. SQL语言分类DQL,DML,DDL,DCL,DTL

    SQL语言共分为五大类: 数据查询语言DQL 数据操纵语言DML 数据定义语言DDL 数据控制语言DCL 数据事物语言DTL DQL 数据查询语言DQL基本结构是由SELECT子句,FROM子句,WH ...

  5. 最小费用最大流spfa

    #include <iostream> #include <cstring> #include <cstdio> #include <queue> #d ...

  6. xslt格式化日期的方法

    数据:<PK_SEND_DATE>2007-9-28 0:00:00</PK_SEND_DATE> 通过截取:<xsl:value-of select="sub ...

  7. MT【240】6*6放黑白子

    $6*6$的方格中放三个完全相同的黑子和三个完全相同的白子,要求每行每列都有一个棋子,且每一格只有一个棋子.问有多少不同放法? 解:$\dfrac{36*25*16*9*4*1}{3!*3!}=144 ...

  8. luogu2577/bzoj1899 午餐 (贪心+dp)

    首先,应该尽量让吃饭慢的排在前面,先按这个排个序 然后再来决定每个人到底去哪边 设f[i][j]是做到了第i个人,然后1号窗口目前的总排队时间是j,目前的最大总时间 有这个i和j的话,再预处理出前i个 ...

  9. 【codeforces 768F】 Barrels and boxes

    http://codeforces.com/problemset/problem/768/F (题目链接) 题意 A,B两种物品可以装到栈中,每个栈只能存放一种物品,容量没有限制.现在讲所有栈排成一列 ...

  10. A1086. Tree Traversals Again

    An inorder binary tree traversal can be implemented in a non-recursive way with a stack. For example ...