LINK

题意:询问是否存在直线,使得所有线段在其上的投影拥有公共点

思路:如果投影拥有公共区域,那么从投影的公共区域作垂线,显然能够与所有线段相交,那么题目转换为询问是否存在直线与所有线段相交。判断相交先求叉积再用跨立实验。枚举每个线段的起始结束点作为直线起点终点遍历即可。

/** @Date    : 2017-07-12 14:35:44
* @FileName: POJ 3304 基础线段交判断.cpp
* @Platform: Windows
* @Author : Lweleth (SoungEarlf@gmail.com)
* @Link : https://github.com/
* @Version : $Id$
*/
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <utility>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <stack>
#include <queue>
#include <math.h>
//#include <bits/stdc++.h>
#define LL long long
#define PII pair<int ,int>
#define MP(x, y) make_pair((x),(y))
#define fi first
#define se second
#define PB(x) push_back((x))
#define MMG(x) memset((x), -1,sizeof(x))
#define MMF(x) memset((x),0,sizeof(x))
#define MMI(x) memset((x), INF, sizeof(x))
using namespace std; const int INF = 0x3f3f3f3f;
const int N = 1e5+20;
const double eps = 1e-8; struct point
{
double x, y;
point(double _x, double _y){x = _x, y = _y;}
point(){}
point operator -(const point &b) const
{
return point(x - b.x, y - b.y);
}
double operator *(const point &b) const
{
return x * b.x + y * b.y;
}
double operator ^(const point &b) const
{
return x * b.y - y * b.x;
}
}; struct line
{
point s, t;
line(){}
line(point ss, point tt){s = ss, t = tt;}
}; double cross(point a, point b)
{
return a.x * b.y - a.y * b.x;
} double xmult(point p1, point p2, point p0)
{
return (p1 - p0) ^ (p2 - p0);
} double distc(point a, point b)
{
return sqrt((b - a) * (b - a));
} bool opposite(point p1, point p2, line l)
{
double t = xmult(l.s, l.t, p1) * xmult(l.s, l.t, p2);
printf("%.8lf\n", t);
return xmult(l.s, l.t, p1) * xmult(l.s, l.t, p2) < -eps;
} //线段与线段交
bool Sjudgeinter(line a, line b)
{
return opposite(b.s, b.t, a) && opposite(a.s, a.t, b);
} int sign(double x)
{
if(fabs(x) < eps)
return 0;
if(x < 0)
return -1;
return 1;
}
//线段与直线交 a为直线
bool judgeinter(line a, line b)
{
//return opposite(b.s, b.t, a);
/*double x = xmult(a.s, a.t, b.s);
double y = xmult(a.s, a.t, b.t);
printf("@%.4lf %.4lf\n", x, y);*/
return sign(xmult(a.s, a.t, b.s)) * sign(xmult(a.s, a.t, b.t)) <= 0;
} int n;
point p[200];
line l[200];
bool check(line li)
{
if(sign(distc(li.s, li.t)) == 0)
return 0;
for(int i = 0; i < n; i++)
if(judgeinter(li, l[i]) == 0)
return 0;
return 1;
} int main()
{
int T;
cin >> T;
while(T--)
{
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
double x1, x2, y1, y2;
scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
p[i] = point(x1, y1), p[i + 1] = point(x2, y2);
l[i] = line(p[i], p[i + 1]);
}
int ans = 0;
/*for(int i = 0; i < n * 2; i++)//不知道为啥直接枚举所有点就是WA
{
for(int j = 0; j < n * 2; j++)
{
if(ans)
break;
if(i == j || distc(p[i],p[j]) < eps)
continue;
line tmp = line(p[i], p[j]);
if(p[i].x == p[j].x && p[i].y == p[j].y)//考虑到枚举直线为重合点
continue;
int flag = 0;
for(int k = 0; k < n; k++)
{
if(k == 1)
printf("**");
if(judgeinter(tmp, l[k]) == 0)
{
flag = 1;
break;
} }
if(!flag)
ans = 1;
cout << i << "~"<< j << endl;
}
}*/
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
if(check(line(l[i].s, l[j].s))
|| check(line(l[i].s,l[j].t))
|| check(line(l[i].t, l[j].s))
|| check(line(l[i].t, l[j].t)) )
{
ans = 1;
break;
}
}
}
printf("%s\n", ans?"Yes!":"No!");
}
return 0;
}
//询问是否存在直线,使得所有线段在其上的投影拥有公共点
//如果存在公共区域,对其作垂线,那么其垂线必定过所有的线段
//那么转换为是否存在直线 与所有线段都相交

POJ 3304 Segments 基础线段交判断的更多相关文章

  1. POJ 3304 Segments (叉乘判断线段相交)

    <题目链接> 题目大意: 给出一些线段,判断是存在直线,使得该直线能够经过所有的线段.. 解题思路: 如果有存在这样的直线,过投影相交区域作直线的垂线,该垂线必定与每条线段相交,问题转化为 ...

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

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

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

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

  4. POJ 3304 Segments(计算几何:直线与线段相交)

    POJ 3304 Segments 大意:给你一些线段,找出一条直线可以穿过全部的线段,相交包含端点. 思路:遍历全部的端点,取两个点形成直线,推断直线是否与全部线段相交,假设存在这种直线,输出Yes ...

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

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

  6. [poj] 3304 Segments || 判断线段相交

    原题 给出n条线段,判断是否有一条直线与所有线段都有交点 若存在这样一条直线,那么一定存在一条至少过两个线段的端点的直线满足条件. 每次枚举两条线段的两个端点,确定一条直线,判断是否与其他线段都有交点 ...

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

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

  8. POJ 1556 The Doors 线段交 dijkstra

    LINK 题意:在$10*10$的几何平面内,给出n条垂直x轴的线,且在线上开了两个口,起点为$(0, 5)$,终点为$(10, 5)$,问起点到终点不与其他线段相交的情况下的最小距离. 思路:将每个 ...

  9. poj 3304 Segments(解题报告)

    收获:举一反三:刷一道会一道 1:思路转化:(看的kuangbin的思路) 首先是在二维平面中:如果有很多线段能够映射到这个直线上并且至少重合于一点,充要条件: 是过这个点的此条直线的垂线与其他所有直 ...

随机推荐

  1. eclipse连接SQL2008R2

    最近又开始写JAVA WEB了,想起连接数据库就麻烦,但是通过一天的努力我居然弄好了,很有成就感. 我用的是 SQL Server 2008 R2  +  eclipse 首先要成功的安装好SQL最终 ...

  2. PAT L1 - 056 猜数字

    https://pintia.cn/problem-sets/994805046380707840/problems/994805074646122496 一群人坐在一起,每人猜一个 100 以内的数 ...

  3. (六)Jmeter重要组件的执行顺序及作用域

    一.Jmeter重要组件: 1)配置元件---Config Element: 用于初始化默认值和变量,以便后续采样器使用.配置元件大其作用域的初始阶段处理,配置元件仅对其所在的测试树分支有效,如,在同 ...

  4. DNS原理及解析过程

    本文主要参考自:http://369369.blog.51cto.com/319630/812889 并做了小幅修改 什么是DNS? 因特网上的主机和人类一样,也可以使用多种方式进行识别.主机的一种识 ...

  5. 第132天:移动web端-rem布局(进阶)

    rem布局(进阶版) 该方案使用相当简单,把下面这段已压缩过的 原生JS(仅1kb,源码已在文章底部更新,2017/5/3) 放到 HTML 的 head 标签中即可(注:不要手动设置viewport ...

  6. MVC4中control的增删改查

    public class TestController : Controller { private LeaveEntities db = new LeaveEntities(); // // GET ...

  7. Spring AOP基础

    目录 AOP基本术语 Advice-通知 Before After After-returning After-throwing Around Pointcut-切点 Aspect-切面 Join P ...

  8. HDU4669_Mutiples on a circle

    题目的意思是给你一些数字a[i](首位相连),现在要你选出一些连续的数字连续的每一位单独地作为一个数位.现在问你有多少种选择的方式使得选出的数字为k的一个倍数. 其实题目是很简单的.由于k不大(200 ...

  9. BZOJ 1975 魔法猪学院(A*求K短路)

    显然每次贪心的走最少消耗的路径即可.那么也就是找出最短路,次短路,,,K短路之后消耗E的能量的最多的路径条数. 也就是裸的A*算法. #include <bits/stdc++.h> us ...

  10. Day 2 笔记 数据结构

    Day 2 笔记 数据结构 1.栈.队列.链表等数据结构都是线性数据结构 2.树状数据结构:二叉堆,线段树,树状数组,并查集,st表... 优先队列其实与二叉堆的存储方式并不相同. 一.二叉堆 1.二 ...