题意:给你一些线段,问与第i根线段相交的线段有几根。。
思路:计算几何+并查集
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> using namespace std; const int N = 1009; const double INF = 1e20 , EPS = 1E-6; bool zero(double x){ return -EPS<x&&x<EPS; } struct cvector{ double x,y; cvector(){}; cvector(double a,double b){x=a,y=b;} }; double operator^(cvector p,cvector q){ return p.x*q.y-q.x*p.y; } double operator *(cvector p,cvector q){ return p.x*q.x+p.y*q.y; } struct cpoint{ double x,y; cpoint(double a,double b){ x = a,y = b; } cpoint(){} }; cvector operator -(cpoint a, cpoint b){ ///向量ab return cvector(b.x-a.x, b.y-a.y); } struct cline{ cpoint a,b; } re[N]; bool dots_inline(cpoint p1,cpoint p2,cpoint p3){///判三点共线 return zero((p2-p1)^(p3-p1)); } bool same_side(cpoint p1,cpoint p2,cline l){ ///两点在线段同侧 cvector v0=l.b-l.a; cvector v1=p1-l.a,v2=p2-l.a; return (v1^v0)*(v2^v0)>EPS; } bool dot_onseg(cpoint p,cline ll){ /// 点在线段上 if(!dots_inline(p,ll.a,ll.b)) return false; cvector v1=ll.b-ll.a,v2=p-ll.a; cvector v3=ll.a-ll.b,v4=p-ll.b; if(v1*v2>-EPS&&v3*v4>-EPS) return true; return false; } bool intersect_in(cline u,cline v){ ///线段相交,包括交点和重合 if(!dots_inline(u.a,u.b,v.a)||!dots_inline(u.a,u.b,v.b)) return !same_side(u.a,u.b,v)&&!same_side(v.a,v.b,u); return dot_onseg(u.a,v)||dot_onseg(u.b,v) ||dot_onseg(v.a,u)||dot_onseg(v.b,u); } int fa[N]; int finfa(int k) { if(fa[k]==k) return k; return fa[k] = finfa(fa[k]); } void un(int a,int b) { fa[finfa(a)] = fa[finfa(b)]; } bool xx(int a,int b) { return intersect_in(re[a],re[b]); } int main() { freopen("in.txt","r",stdin); int cas,ou=0,n,tmp,cnt; char ar[3]; cpoint a,b; scanf("%d",&cas); while(cas--) { cnt = 0; if(ou) printf("\n");ou = true; scanf("%d",&n); for(int i=0;i<=n;i++) fa[i] = i; while(n--) { scanf("%s",ar); if(ar[0]=='P') { scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y); re[cnt].a=a,re[cnt].b=b; for(int i=0;i<cnt;i++) { if(finfa(i)!=finfa(cnt)&&xx(i,cnt)) { un(i,cnt); } }cnt++; } else { scanf("%d",&tmp);tmp--; //cout<<tmp<<" "<<cnt<<endl; int f = finfa(tmp),ans = 0; for(int i=0;i<cnt;i++) if(finfa(i)==f) ans++; printf("%d\n",ans); } } } return 0; }