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. alpha6/10

    队名:Boy Next Door 燃尽图 晗(组长) 今日完成 学习了css的一些基本操作. 明日工作 抽空把javascript的基本操作学习一下 还剩下哪些任务 微信API还有京东钱包的API. ...

  2. 使用字符界面 qemu-kvm 创建虚拟机

    qemu-kvm的基本用法:指定系统类型,CPU运行模式,NUMA(Non Uniform Memory Access Architecture), 软驱设备,光驱设备,硬件设备   # 查看qemu ...

  3. ansible介绍和安装

    ansible是由 Python 编写的强大的配置管理解决方案,ansible 的特点就在于它的简洁与高效率 ansible与其他的配置管理工具不同点在于:不需要你在想要配置的每个节点上安装自己的组件 ...

  4. Spring boot整合shiro框架(2)

    form提交 <form th:action="@{/login}" method="POST"> <div class="form ...

  5. Vue父组件与子组件传递事件/调用事件

    1.Vue父组件向子组件传递事件/调用事件 <div id="app"> <hello list="list" ref="child ...

  6. SPOJ3713——Primitive Root

    终于有一个SPOJ题目是我自己独立做出来的,ORZ,太感动了. 题目意思是给你一个素数,问你一个数r是否满足,r,r^2,r^3,……,r^p-1,全不相同. 以前做过这种类型的题目额.是这样的. 根 ...

  7. namesapce的作用 增加访问路径 目的:区分不同包的相同action的访问路径

  8. Jmeter远程启动负载机

    1.负载机下载Jmeter,设置环境变量,jmeter中进行启动jmeter-server的应用服务.环境变量设置如下: 变量名:JMETER_HOME 变量值:C:\Program Files\ap ...

  9. [CF1111D]Destroy the Colony

    题目大意:有一个长度为$n(n\leqslant10^5,n=0\pmod2)$的字符串,字符集大小为$52$,有$q(q\leqslant10^5)$次询问,每次询问第$x,y$个字符在这个字符串的 ...

  10. 【MVVM Dev】PART_Editor的使用

    一.前言       在日常的界面开发中,我们大多使用MVVM模式进行开发.通常情况下,一个PropertyGridControl或者DataGrid的ItemsSource设置好, 然后每一列绑定好 ...