UOJios
爲了方便,咱們假定最後一條直線是從上往下穿過來的,好比說把它當成座標系的\(y\)軸。
因而咱們能夠處理出全部交點,而後把它們從上往下排序。
相鄰的兩個點就構成了一個相交的平面(能夠認爲正無窮和負無窮位置還有一個點)
那麼,這個區間是有限的,當且僅當過這個兩點的直線在左側都還能找到一個交點,在右側也還能找到一個交點。
因而考慮怎麼找交點,兩側基本等價,因此拆開考慮,好比考慮右側。
咱們從上往下依次掃每個過每個交點的直線,若是在這條直線上方存在一條直線,知足斜率小於這條直線,那麼就會和這條直線有交,因而咱們能夠維護一些斜率的單調棧,每次二分一段區間,找到最靠上的那個,那麼這一段區間內的全部點的右側都是封閉的,差分一下就能夠知道全部點的狀況;左側的狀況是相似的。spa
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<vector> using namespace std; #define ll long long #define MAX 100100 const double Pi=acos(-1),eps=1e-7; inline int read() { int x=0;bool t=false;char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-')ch=getchar(); if(ch=='-')t=true,ch=getchar(); while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar(); return t?-x:x; } struct Node{double x,y;}G[MAX]; double Len(Node a){return sqrt(a.x*a.x+a.y*a.y);} Node operator+(Node a,Node b){return (Node){a.x+b.x,a.y+b.y};} Node operator-(Node a,Node b){return (Node){a.x-b.x,a.y-b.y};} Node operator*(Node a,double b){return (Node){a.x*b,a.y*b};} double Cross(Node a,Node b){return a.x*b.y-a.y*b.x;} struct Line{Node p,v;}L[MAX],pL[MAX]; Node Intersection(Line a,Line b) { Node c=b.p-a.p; double t=Cross(b.v,c)/Cross(b.v,a.v); return a.p+a.v*t; } bool Parallel(Line a,Line b){return fabs(Cross(a.v,b.v))<1e-9;} Node Turn(Node a,double alp){return (Node){a.x*cos(alp)-a.y*sin(alp),a.x*sin(alp)+a.y*cos(alp)};} int n,id[MAX];double K[MAX]; bool cmpid(int a,int b){return G[a].y>G[b].y;} int St[MAX],cl[MAX],cr[MAX]; double ang[MAX]; int main() { n=read(); for(int i=1;i<=n+1;++i) { double x1=read(),y1=read(),x2=read(),y2=read(); L[i].p=(Node){x1,y1};L[i].v=(Node){x2,y2}; L[i].v=L[i].v-L[i].p;pL[i]=L[i]; } double alpha=Pi/2-atan2(L[n+1].v.y,L[n+1].v.x); for(int i=1;i<=n+1;++i)L[i].p=Turn(L[i].p,alpha); for(int i=1;i<=n+1;++i)L[i].v=Turn(L[i].v,alpha); for(int i=1;i<=n+1;++i)L[i].p=L[i].p-L[n+1].p; for(int i=1;i<=n;++i)K[i]=L[i].v.y/L[i].v.x; for(int i=1;i<=n;++i)G[i]=(Node){0,L[i].p.y-K[i]*L[i].p.x}; for(int i=1;i<=n;++i)id[i]=i; sort(&id[1],&id[n+1],cmpid); for(int i=1,top=0;i<=n;++i) { int x=id[i],l=1,r=top,ret=0; while(l<=r) { int mid=(l+r)>>1; if(K[x]>K[id[St[mid]]]&&!Parallel(pL[x],pL[id[St[mid]]]))ret=mid,r=mid-1; else l=mid+1; } if(ret)cl[St[ret]]++,cl[i]--; else St[++top]=i; } for(int i=1,top=0;i<=n;++i) { int x=id[i],l=1,r=top,ret=0; while(l<=r) { int mid=(l+r)>>1; if(K[x]<K[id[St[mid]]]&&!Parallel(pL[x],pL[id[St[mid]]]))ret=mid,r=mid-1; else l=mid+1; } if(ret)cr[St[ret]]++,cr[i]--; else St[++top]=i; } for(int i=1;i<=n;++i)cl[i]+=cl[i-1],cr[i]+=cr[i-1];cl[n+1]=cr[n+1]=0; for(int i=n;~i;--i) if(cl[i]&&cr[i])putchar(49); else putchar(48); return 0; }