题意:找一条直线让所有的线段在这条
直线的投影交集不为空
转化:题目可以转化为一条直线与所有线段判交。设直线ab为与所有线段
有交的直线,那所有线段在与ab相互垂直的直线上投影的交集至少有一个
交点(即不为空)。
解法:枚举所有不同的点中的两点所组成的直线与所有线段判交。
注意重点的判断。。。。。。。。
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<string> #include<map> #include<math.h> #include<iostream> #include <queue> #include<algorithm> using namespace std; #define inf 2147483647 #define eps 1e-8 #define LL __int64 #define M 5001 struct point { double x,y; }p[205]; struct Line { point p1, p2; }; struct Segment { point p1,p2; }s[105]; double muilt(point p0,point p1,point p2) { return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y); } bool cmp(point a,point b) { if(abs(a.x-b.x)<eps) return a.y<b.y; return a.x<b.x; } int pd(Line l,Segment s) { if(muilt(l.p1,l.p2,s.p1)*muilt(l.p1,l.p2 ,s.p2 )<eps) return 1; return 0; } int main() { int t; scanf("%d",&t); while(t--) { int n; scanf("%d",&n); int i,j,k; j=0; for(i=0;i<n;i++) { scanf("%lf%lf%lf%lf",&s[i].p1.x,&s[i].p1.y,&s[i].p2.x,&s[i].p2.y); p[j].x=s[i].p1.x;p[j++].y=s[i].p1.y; p[j].x=s[i].p2.x;p[j++].y=s[i].p2.y; } int l=j,flag; sort(p,p+j,cmp); for(i=0;i<l;i++) { for(j=i+1;j<l;j++) { if(abs(p[i].x-p[j].x)<eps&&abs(p[i].y-p[j].y)<eps) continue; flag=1; Line line; line.p1=p[i]; line.p2=p[j]; for(k=0;k<n;k++) { if(!pd(line,s[k])) { flag=0; break; } } if(flag) break; } if(flag) break; } if(flag) printf("Yes!\n"); else printf("No!\n"); } return 0; }