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的思路) 首先是在二维平面中:如果有很多线段能够映射到这个直线上并且至少重合于一点,充要条件: 是过这个点的此条直线的垂线与其他所有直 ...
随机推荐
- 04慕课网《vue.js2.5入门》——Vue-cli开发todolist
主要文件目录: 文件代码: 根实例,初始化vue: <!--index.html,网站入口页面,和main.jsp组成一套.vue文件,包含--> <!DOCTYPE html> ...
- 第一次c++团队合作项目第二篇随笔
随着时间的推移,项目也逐渐展开.我的地图也通过按钮的拼接完成了一小部分.这部分我是用了QT上的按钮类来实现的.接下来就是给按钮贴上图片,然后最重要也是最困难的是实现参数的传递,如何实现点击一个英雄或小 ...
- 中国剩余定理---FZU 1402 猪的安家
J - 猪的安家 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Sta ...
- 第六章 过滤器Filter
Filter概述 Filter不用于客户端请求,只用于对request,response进行修改或对context,session,request事件进行监听. 1.概述 如上图,多个filter组成 ...
- OSG学习:阴影代码示例
效果图: 代码示例: #include <osgViewer/Viewer> #include <osg/Node> #include <osg/Geode> #i ...
- 基于图形学混色问题OpenGl的收获
void myDisplay(void) {glClearColor(0.0f,0.0f,0.0f,1.0f); glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_B ...
- javac和java的使用
java -Xmx128m -Dfile.encoding=gbk -cp ./;bin/;./*;lib/* com.qianlima.crawlOthers.Icp REM REM block e ...
- 第197天:js---caller、callee、constructor和prototype用法
一.caller---返回函数调用者 //返回函数调用者 //caller的应用场景 主要用于察看函数本身被哪个函数调用 function fn() { //判断某函数是否被调用 if (fn.cal ...
- CF708C-Centroids
题目 一棵树的重心定义为一个点满足删除这个点后最大的连通块大小小于等于原来这颗树大小的一半. 给出一棵树,一次操作为删除一条边再添加一条边,操作结束后必须仍为一棵树.问这颗树的每个点是否可以通过一次操 ...
- Android Espresso(UI自动化测试)的搭建
Espresso是Google官方提供的Android UI自动化测试的框架. 为什么叫Espresso(浓咖啡),好像是想让Android码农们轻松的写完自动化用例后能享受着咖啡,看着自动化测试&q ...