题意:
给你n条线段,问你是否存在一条直线穿过所有的线段。
思路:
枚举线段的两个端点(x1,y1)、(x2,y2)做一条直线,该直线方程为,然后利用式子
来判断线段(x1,y1)-(x2-y2)是否与直线相交。
#include<cstdio>
const int MAX=105;
struct Segment{
double x1,x2,y1,y2;
}seg[MAX];
struct Point{
double x,y;
}p[MAX*2];
int n;
bool ok(int i,int j){
if(p[i].x==p[j].x) return false;
double ki=(p[j].y-p[i].y)/(p[j].x-p[i].x);
for(int k=1;k<=n;k++){
double t1=(seg[k].y1-p[i].y)-ki*(seg[k].x1-p[i].x);
double t2=(seg[k].y2-p[i].y)-ki*(seg[k].x2-p[i].x);
if(t1*t2>0) return false;
}
return true;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lf%lf%lf%lf",&seg[i].x1,&seg[i].y1,&seg[i].x2,&seg[i].y2);
p[i*2-1].x=seg[i].x1,p[i*2-1].y=seg[i].y1;
p[i*2].x=seg[i].x2,p[i*2].y=seg[i].y2;
}
bool flag=false;
for(int i=1;i<=n*2;i++){
for(int j=i+1;j<=n*2;j++){
if(ok(i,j)){
flag=true;
break;
}
}
if(flag) break;
}
if(flag) printf("Yes!\n");
else printf("No!\n");
}
return 0;
}