如果一条直线经过了所有线段,那么把这条直线旋转之后,边界就是卡在两个线段的端点处
那么就可以遍历每两个端点,判断这两个端点组成的直线是否穿过了所有的线段,如果是,则存在,不是继续找,找不到就不存在
如何判断一条直线是否经过了所有点呢?挨个判断这条线是否穿过线段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| #include <bits/stdc++.h>
#define debug freopen("in.txt","r",stdin); freopen("out.txt","w",stdout) #define ios ios::sync_with_stdio(0);cin.tie(0);cout.tie(0) using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pii; const int MAXN=1e6+100; const int MOD=1e9+7; const int INF=0x3f3f3f3f; const int SUB=-0x3f3f3f3f; const double eps=1e-8; const double E=exp(1); const double pi=acos(-1); int t,n,tail; struct point{ double x,y; }pt[MAXN]; double cross(point a,point b,point c){ return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y); } int fcmp(double x,double y){ if(fabs(x-y)<eps) return 0; else if(x>y) return 1; else return -1; } int sign(double x){ if(fabs(x)<=eps) return 0; else if(x>0) return 1; else return -1; } bool check(double x1,double y1,double x2,double y2){ point q1={x1,y1},q2={x2,y2}; for(int k=1;k<=tail;k+=2){ if(sign(cross(q1,q2,pt[k]))*sign(cross(q1,q2,pt[k+1]))>0) return 0; } return 1; } int main(){ ios; cin>>t; while(t--){ tail=0; cin>>n; for(int i=1;i<=n;i++){ double x1,y1,x2,y2; cin>>x1>>y1>>x2>>y2; pt[++tail]={x1,y1}; pt[++tail]={x2,y2}; } int flag=0; for(int i=1;i<tail;i++){ for(int j=i+1;j<=tail;j++){ if(!fcmp(pt[i].x,pt[j].x) && !fcmp(pt[i].y,pt[j].y)) continue; if(check(pt[i].x,pt[i].y,pt[j].x,pt[j].y)) flag=1; if(flag) break; } if(flag) break; } if(flag) cout<<"Yes!\n"; else cout<<"No!\n"; } return 0; }
|