题意:给定n条线段,确定是否存在一条直线,使得这n条线段在这条直线上的射影具有公共点
可将问题转化为是否存在一条直线经过所有的线段,证明见依然的博客:http://blog.sina.com.cn/s/blog_6635898a0100n2lv.html
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const double eps = 1e-8;
const int maxn = 111;
int n;
struct Point {
double x, y;
};
struct Line {
Point a, b;
} line[maxn];
double Multi(Point p1, Point p2, Point p0) {
return (p1.x - p0.x) * (p2.y - p0.y) - (p1.y - p0.y) * (p2.x - p0.x);
}
bool Check(Point a, Point b) {
if (fabs(a.x-b.x) < eps && fabs(a.y-b.y) < eps) return false;
for (int i = 0; i < n; i++)
if (Multi(line[i].a, b, a) * Multi(line[i].b, b, a) > eps) return false;
return true;
}
int main()
{
int t, i, j;
bool flag;
scanf ("%d", &t);
while (t--) {
scanf ("%d", &n);
for (i = 0; i < n; i++)
scanf ("%lf%lf%lf%lf", &line[i].a.x, &line[i].a.y, &line[i].b.x, &line[i].b.y);
flag = false;
if (n < 3) flag = true;
for (i = 0; i < n && !flag; i++) {
if (Check(line[i].a, line[i].b)) flag = true;
for (j = i + 1; j < n && !flag; j++) {
if (Check(line[i].a, line[j].a) ||
Check(line[i].a, line[j].b) ||
Check(line[i].b, line[j].a) ||
Check(line[i].b, line[j].b))
flag = true;
}
}
if (flag) printf ("Yes!\n");
else printf ("No!\n");
}
return 0;
}