1. 程式人生 > >[poj] 3304 Segments || 判斷線段相交

[poj] 3304 Segments || 判斷線段相交

int cst put -- struct -a ace def point

原題

給出n條線段,判斷是否有一條直線與所有線段都有交點


若存在這樣一條直線,那麽一定存在一條至少過兩個線段的端點的直線滿足條件。
每次枚舉兩條線段的兩個端點,確定一條直線,判斷是否與其他線段都有交點。

判斷交點:
判斷AB和CD是否相交,即判斷AC×BD(叉積)和AD×BC(叉積)是否同號

#include<cstdio>
#define eps 1e-13
#define N 110
using namespace std;
int t,n;
struct point
{
    double x,y;
    point() {}
    point(double _x,double
_y) : x(_x),y(_y) {} double operator * (const point &b) const { return x*b.y-b.x*y; } point operator - (const point &b) const { return point(b.x-x,b.y-y); } bool operator == (const point &b) const { return x==b.x && y==b.y; } void
read() { scanf("%lf%lf",&x,&y); } }; struct hhh { point s,t; }a[N]; bool check(point aa,point bb) { if (aa==bb) return 0; for (int i=1;i<=n;i++) if (((aa-a[i].s)*(aa-bb))*((aa-a[i].t)*(aa-bb))>eps) return 0; return 1; } bool solve() { for
(int i=1;i<=n;i++) for (int j=i+1;j<=n;j++) if (check(a[i].s,a[j].t) || check(a[j].s,a[i].t)) return 1; else if (check(a[i].s,a[j].s) || check(a[i].t,a[j].t)) return 1; return 0; } int main() { scanf("%d",&t); while (t--) { scanf("%d",&n); for (int i=1;i<=n;i++) a[i].s.read(),a[i].t.read(); if (n<3 || solve()) puts("Yes!"); else puts("No!"); } return 0; }

[poj] 3304 Segments || 判斷線段相交