您的位置:首页 > 其它

POJ3304--Segments

2015-08-25 22:46 267 查看
题目大意:给定一些线段,问是否有直线L存在,使得所有线段到L的投影有至少一个公共点。

分析:实际上就是问,是否存在一条直线K, 和所有这些线段都相交。L是K的垂线即可。若存在一条直线与所有线段相交,该直线必定经过这些线段的某两个端点(否则可以平移或转动使之靠上端点)。枚举任意两个端点构造直线并看它是否与每条线段相交即可。

代码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;

#define eps 1e-8

struct P {
double x, y;
P() {}
P(double x, double y):x(x), y(y) {}
}p[300];

struct Seg {
P p1, p2;
}ss[110];
int n;

P operator -(P p, P q) {
return P(p.x-q.x, p.y-q.y);
}

double dist(P v1, P v2){
return sqrt((v1.x-v2.x)*(v1.x-v2.x)+(v1.y-v2.y)*(v1.y-v2.y));
}

double Cross(const P & v1, const P & v2) {
return v1.x * v2.y - v1.y * v2.x;
}

bool ok(P p1, P p2) {
if(dist(p1, p2) < eps) return false;
else {
for(int i = 0; i < n; i++) {
if(Cross(p2 - p1, ss[i].p1 - p1)*
Cross(p2 - p1, ss[i].p2 - p1) > eps)
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", &ss[i].p1.x, &ss[i].p1.y, &ss[i].p2.x, &ss[i].p2.y);
int flag = 0;
if(n == 1) {
flag = 1;
}
else {
for(int i = 0; i < n-1 && !flag; i++)
for(int j = i+1; j < n && !flag; j++) {
if(ok(ss[i].p1, ss[j].p1) ||
ok(ss[i].p1, ss[j].p2) ||
ok(ss[i].p2, ss[j].p1) ||
ok(ss[i].p2, ss[j].p2))
flag = 1;
}
}
if(flag) printf("Yes!\n");
else printf("No!\n");

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: