题意:求是否有一条直线,满足题目给出的所有线段在其上的投影任意两个都有公共部分。
看了题解。。。
如果存在这条线,那么一定存在某条垂线,与所有线段都相交,于是问题转化为求一条直线与所有线段相交。
另外,YY可知,如果存在这种线,那么一定存在一条满足条件的线,其经过所有线段的端点中的两个。
于是,枚举端点即可。
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const double eps = 1e-8;
typedef struct Point {
double x, y;
}Point;
typedef struct Line {
Point pt[2];
}Line;
typedef struct Segment {
Point pt[2];
}Segment;
typedef struct Vector {
double x, y;
}Vector;
double product(Vector v1, Vector v2)
{
return v1.x * v2.y - v2.x * v1.y;
}
const int maxn = 110;
Segment seg[maxn];
bool check(Line ln, Segment s0)
{
Vector v1, v2, v3;
v1.x = ln.pt[1].x - ln.pt[0].x;
v1.y = ln.pt[1].y - ln.pt[0].y;
v2.x = s0.pt[0].x - ln.pt[0].x;
v2.y = s0.pt[0].y - ln.pt[0].y;
v3.x = s0.pt[1].x - ln.pt[0].x;
v3.y = s0.pt[1].y - ln.pt[0].y;
double p = product(v1, v2) * product(v1, v3);
return p == 0 || p < 0;
}
int main()
{
int t;
for(scanf("%d", &t); t--;) {
int n;
bool yes;
scanf("%d", &n);
for(int i = 0; i < n; i++)
scanf("%lf%lf%lf%lf", &seg[i].pt[0].x, &seg[i].pt[0].y, &seg[i].pt[1].x, &seg[i].pt[1].y);
for(int i = 0; i < n; i++) {
for(int j = 0; j <= i; j++) {
for(int k = 0; k < 2; k++) {
for(int q = 0; q < 2; q++) {
Point pa = seg[i].pt[k], pb = seg[j].pt[q];
if(pa.x == pb.x && pa.y == pb.y) continue;
Line ln;
ln.pt[0] = pa, ln.pt[1] = pb;
yes = true;
for(int p = 0; p < n; p++) {
if(!check(ln, seg[p])) {
yes = false;
break;
}
}
if(yes) goto ans;
}
}
}
}
ans:puts(yes ? "Yes!" : "No!");
}
return 0;
}