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的思路) 首先是在二维平面中:如果有很多线段能够映射到这个直线上并且至少重合于一点,充要条件: 是过这个点的此条直线的垂线与其他所有直 ...
随机推荐
- 随机生成四则运算式2-NEW+PSP项目计划(补充没有真分数的情况)
PS:这是昨天编写的随机生成四则运算式2的代码:http://www.cnblogs.com/wsqJohn/p/5264448.html 做了一些改进. 补:在上一次的运行中并没有加入真分数参与的运 ...
- 福大软工·第十一次作业-Alpha事后诸葛亮
福大软工·第十一次作业-Alpha事后诸葛亮 组长博客链接 本次作业博客链接 项目Postmortem 模板 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描 ...
- Robotium之“去哪儿旅行”
Robotium基于APK自动化测试,只有APK文件,没有源代码. Eclipse 默认的debug keystore可以在Windows->Preferences->Android-&g ...
- vscode如何用浏览器预览运行html文件
1,打开vscode编辑器,点击编辑器主界面左上侧第五个小图标——‘扩展’按钮: 2,进入扩展搜索右拉框,在应用商店搜索框中输入“view in browser”会自动进行搜索 3,等待几秒钟时间,扩 ...
- 卸载iptables 小心了!!怎么关闭和卸载iptables
千万千万不要使用下面的命令卸载iptables yum remove iptables 这样操作会卸载掉很多系统必要的组件,那就开不了机了,链接不上了.切记切记. 如果想永远停用,使用以下命令即可: ...
- POJ3378_Crazy Thairs
这个题目很有意思,也是一个很好的题目,涉及的知识点比较广,要求较高. 题目是这样的,给定你一个n个数的数列,问你有多少个长度为5的上升序列. 首先看到有50000,我们就知道肯定不会是DP.(但是不知 ...
- POJ2374_Fence Obstacle Course
题意是描述是这样的,给你n个围栏,对于每个围栏你必须走到其边上才可以往下跳,现在问你从初始最高位置的n个围栏,到原点,水平走过的路程最少是多少? 其实我可可以这样来考虑问题.由于每次都是从板子的左右两 ...
- 题解 P2955 【[USACO09OCT]奇数偶数Even? Odd? 】
很明显这题是个假入门! 小金羊一不小心点进题解发现了内幕 能看的出来都WA过Unsigned long long int 做题可以用Python,Python的变量虽然 强悍的不行! 但是我们可以用字 ...
- 洛谷 P2421 A-B数对(增强版)
题目描述 给出N 个从小到大排好序的整数,一个差值C,要求在这N个整数中找两个数A 和B,使得A-B=C,问这样的方案有多少种? 例如:N=5,C=2,5 个整数是:2 2 4 8 10.答案是3.具 ...
- WIN7 右下角音量图标不见了
1.呼叫出 任务管理器,结束掉 explorer.exe 进程 2.新建任务,浏览,找到 C:/windows/system32/systray.exe,确定加载 3.新建任务,输入explorer ...