题意:给定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; }