POJ 3304 Segments 基础线段交判断
题意:询问是否存在直线,使得所有线段在其上的投影拥有公共点
思路:如果投影拥有公共区域,那么从投影的公共区域作垂线,显然能够与所有线段相交,那么题目转换为询问是否存在直线与所有线段相交。判断相交先求叉积再用跨立实验。枚举每个线段的起始结束点作为直线起点终点遍历即可。
/** @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 基础线段交判断的更多相关文章
- POJ 3304 Segments (叉乘判断线段相交)
<题目链接> 题目大意: 给出一些线段,判断是存在直线,使得该直线能够经过所有的线段.. 解题思路: 如果有存在这样的直线,过投影相交区域作直线的垂线,该垂线必定与每条线段相交,问题转化为 ...
- POJ 3304 Segments 判断直线和线段相交
POJ 3304 Segments 题意:给定n(n<=100)条线段,问你是否存在这样的一条直线,使得所有线段投影下去后,至少都有一个交点. 思路:对于投影在所求直线上面的相交阴影,我们可以 ...
- POJ 3304 Segments(判断直线与线段是否相交)
题目传送门:POJ 3304 Segments Description Given n segments in the two dimensional space, write a program, ...
- POJ 3304 Segments(计算几何:直线与线段相交)
POJ 3304 Segments 大意:给你一些线段,找出一条直线可以穿过全部的线段,相交包含端点. 思路:遍历全部的端点,取两个点形成直线,推断直线是否与全部线段相交,假设存在这种直线,输出Yes ...
- POJ 3304 Segments (判断直线与线段相交)
题目链接:POJ 3304 Problem Description Given n segments in the two dimensional space, write a program, wh ...
- [poj] 3304 Segments || 判断线段相交
原题 给出n条线段,判断是否有一条直线与所有线段都有交点 若存在这样一条直线,那么一定存在一条至少过两个线段的端点的直线满足条件. 每次枚举两条线段的两个端点,确定一条直线,判断是否与其他线段都有交点 ...
- Segments POJ 3304 直线与线段是否相交
题目大意:给出n条线段,问是否存在一条直线,使得n条线段在直线上的投影有至少一个公共点. 题目思路:如果假设成立,那么作该直线的垂线l,该垂线l与所有线段相交,且交点可为线段中的某两个交点 证明:若有 ...
- POJ 1556 The Doors 线段交 dijkstra
LINK 题意:在$10*10$的几何平面内,给出n条垂直x轴的线,且在线上开了两个口,起点为$(0, 5)$,终点为$(10, 5)$,问起点到终点不与其他线段相交的情况下的最小距离. 思路:将每个 ...
- poj 3304 Segments(解题报告)
收获:举一反三:刷一道会一道 1:思路转化:(看的kuangbin的思路) 首先是在二维平面中:如果有很多线段能够映射到这个直线上并且至少重合于一点,充要条件: 是过这个点的此条直线的垂线与其他所有直 ...
随机推荐
- DCOM初步窥探二
1.COM进程透明性表现在“组件对象和客户程序可以拥有各自的空间,也可以共享同一个进程空间”. COM负责把客户的调用正确传到组件对象中,并保证参数传递的正确性. 组件对象和客户代码不必考虑调用传递的 ...
- phpdisk 盲注 &前台任意用户登录
代码审核 文件 plugins\phpdisk_client\passport.php 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 $str ...
- 浅谈 Sql Server 触发器
一.触发器概念 1.1.触发器特征 1.1.1.触发器是在对表进行增.删.改时,自动执行的存储过程.触发器常用于强制业务规则,它是一种高级约束,通过事件进行触发而被执行. ...
- Mware中CentOS设置静态IP
Mware中CentOS设置静态IP 因为之前搭建的MongoDB分片没有采用副本集,最近现网压力较大,所以准备研究一下,于是在自己电脑的虚拟机中搭建环境,但是发现之前VMware设置的是DHCP ...
- 选项卡控件(TabControl)的操作
移除选项卡和删除不同:前者可以从控件中移除不需要的选项,后者可以删掉整个控件.
- 理解promise 02
1:promise是什么? 就是(链式)包装的回调函数. 2:语法 new Promise( function(resolve, reject) {...} /* executor */ ); exe ...
- [LeetCode] [LeetCode] Populating Next Right Pointers in Each Node II
Follow up for problem "Populating Next Right Pointers in Each Node". What if the given tre ...
- 【uoj#282】长度测量鸡 结论题
题目描述 给出一个长度为 $\frac{n(n+1)}2$ 的直尺,要在 $0$ 和 $\frac{n(n+1)}2$ 之间选择 $n-1$ 个刻度,使得 $1\sim \frac{n(n+1)}2$ ...
- 洛谷 P1495 曹冲养猪
这是一道标准的孙子定理的题,题意浅显,思路明确 然后我就交了整整16遍啊,欺负人啊,题解暴力就能过,我就TLE ..悲惨的提交记录 下面是题面 题目描述 自从曹冲搞定了大象以后,曹操就开始捉摸让儿子干 ...
- C++解析(6):函数参数的扩展
0.目录 1.函数参数的默认值 2.函数默认参数的规则 3.函数占位参数 4.小结 1.函数参数的默认值 C++可以在函数声明时为参数提供一个默认值 当函数调用时没有提供参数的值,则使用默认值 参数的 ...