题目链接:http://poj.org/problem?id=3304
题目的意思比较有意思。。。
Given n segments in the two dimensional space, write a program, which determines if there exists a line such that after projecting these segments on it, all projected segments have at least one point in common.
题目比较短,翻译一下:
在二维空间上,给你n条线段。写一个程序,决定是否存在这样一条直线---把这n条线段投射到该直线上,所有的投射线段都有至少一个公共点。(line 直线,segment 线段)。
当我们很简单的看到这个问题的时候,我们很的没有头绪。。。
分析:
每条线段在该直线上的最少有一个公共点。。那么过该点一定会有一条直线经过所有的直线。。。。。为什么??可以想象一下, 这是一个二维的平面。。。。
如图: 你们稍微体会一下。。:)
所以我们可以枚举每个点。。组成直线。。直接枚举。然后判断直线和线段相交就好。。
需要区分一下的是。。
线段和线段相交需要判断互相跨立。。。
而直线和线段相交只需要判断线段跨立线段就好。。比较eaey!!!
code:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int N = 1e2 + 5;
const double eps = 1e-9;
struct POINT
{
double x, y;
POINT(){}
POINT(double a, double b){
x = a;
y = b;
}
}p[N * 2];
struct Segment
{
POINT a, b;
Segment(){}
Segment(POINT x, POINT y){
a = x;
b = y;
}
}seg[N];
int n;
double cross(POINT o, POINT a, POINT b)
{
return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);
}
double dis(POINT a, POINT b)
{
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
bool solve(Segment x)
{
for(int i = 0; i < n; i ++){
if(cross(seg[i].a, x.a, x.b) * cross(seg[i].b, x.a, x.b) > eps) // segment x is a line... fuck me.
return false;
}
return true;
}
int main()
{
int T;
scanf("%d", &T);
while(T --){
scanf("%d", &n);
for(int i = 0; i < n; i ++){
scanf("%lf %lf %lf %lf", &seg[i].a.x, &seg[i].a.y, &seg[i].b.x, &seg[i].b.y);
p[i * 2] = seg[i].a; p[i * 2 + 1] = seg[i].b;
}
if(n == 1){
puts("Yes!");
continue;
}
bool flag = false;
for(int i = 0; i < n * 2; i ++){
for(int j = i + 1; j < n * 2 ; j ++)
if(dis(p[i], p[j]) >= eps && solve(Segment(p[i], p[j]))){
flag = true;
}
}
if(flag) puts("Yes!");
else puts("No!");
}
return 0;
}
相对比较简单。。