思路:转换成n条三维空间的直线,求最大的集合使得两两有交点。
有两种情况:第一种是以某2条直线为平面,这时候只要统计这个平面上有几条斜率不同的直线就可以了
还有一种是全部交于同一点,这个也只要判断就可以了。
然后我并不能改出来,wa了好多个点
WA的程序:
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #define dou long double 7 const dou eps=1e-9; 8 int n; 9 struct Point{ 10 dou x,y,z; 11 Point(){} 12 Point(dou x0,dou y0,dou z0):x(x0),y(y0),z(z0){} 13 }; 14 struct Line{ 15 Point s,e,p; 16 int id; 17 Line(){} 18 Line(Point s0,Point e0):s(s0),e(e0){} 19 }l[200005]; 20 int tmp[200005]; 21 int read(){ 22 int t=0,f=1;char ch=getchar(); 23 while (ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();} 24 while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();} 25 return t*f; 26 } 27 bool cmp(Line l1,Line l2){ 28 Point p1=l1.p,p2=l2.p; 29 if (fabs(p1.x-p2.x)<eps&&fabs(p1.y-p2.y)<eps) return p1.z<p2.z; 30 else 31 if (fabs(p1.x-p2.x)<eps) return p1.y<p2.y; 32 return p1.x<p2.x; 33 } 34 bool operator ==(Point p1,Point p2){ 35 return fabs(p1.x-p2.x)<=eps&&fabs(p1.y-p2.y)<=eps&&fabs(p1.z-p2.z)<=eps; 36 } 37 bool operator !=(Point p1,Point p2){ 38 if (p1==p2) return 0; 39 else return 1; 40 } 41 double operator /(Point p1,Point p2){ 42 return p1.x*p2.x+p1.y*p2.y+p1.z*p2.z; 43 } 44 Point operator -(Point p1,Point p2){ 45 return Point(p1.x-p2.x,p1.y-p2.y,p1.z-p2.z); 46 } 47 Point operator *(Point p1,Point p2){ 48 return Point(p1.y*p2.z-p1.z*p2.y,p1.z*p2.x-p1.x*p2.z,p1.x*p2.y-p1.y*p2.x); 49 } 50 Point operator /(Point p1,dou x){ 51 return Point(p1.x/x,p1.y/x,p1.z/x); 52 } 53 dou sqr(dou x){ 54 return x*x; 55 } 56 dou dist(Point p){ 57 return sqrt(sqr(p.x)+sqr(p.y)+sqr(p.z)); 58 } 59 dou dist(Point p1,Point p2){ 60 return dist(p1-p2); 61 } 62 bool zero(dou x){ 63 if (fabs(x)<eps) return 1; 64 return 0; 65 } 66 bool zero(Point p){ 67 return zero(p.x)&&zero(p.y)&&zero(p.z); 68 } 69 bool LineIntersect(Line p1, Line p2){ 70 dou x1=p1.s.x,x2=p1.e.x,x3=p2.s.x,x4=p2.e.x; 71 dou y1=p1.s.y,y2=p1.e.y,y3=p2.s.y,y4=p2.e.y; 72 dou z1=p1.s.z,z2=p1.e.z,z3=p2.s.z,z4=p2.e.z; 73 dou x12=(x1-x2),x13=(x1-x3),x34=(x3-x4); 74 dou y12=(y1-y2),y13=(y1-y3),y34=(y3-y4); 75 dou z12=(z1-z2); 76 dou t=(y34*x12-x34*y12); 77 if (fabs(t)<eps) return 0; 78 return 1; 79 } 80 Point inter(Line p1,Line p2){ 81 dou x1=p1.s.x,x2=p1.e.x,x3=p2.s.x,x4=p2.e.x; 82 dou y1=p1.s.y,y2=p1.e.y,y3=p2.s.y,y4=p2.e.y; 83 dou z1=p1.s.z,z2=p1.e.z,z3=p2.s.z,z4=p2.e.z; 84 dou x12=(x1-x2),x13=(x1-x3),x34=(x3-x4); 85 dou y12=(y1-y2),y13=(y1-y3),y34=(y3-y4); 86 dou z12=(z1-z2); 87 dou t=(y13*x34-y34*x13)/(y34*x12-x34*y12); 88 dou x=x1+x12*((y13*x34-y34*x13)/(y34*x12-x34*y12)); 89 dou y=y1+y12*t,z=z1+z12*t; 90 return Point(x,y,z); 91 } 92 void solve(){ 93 int ans=1; 94 for (int i=1;i<=n;i++){ 95 Point p=l[i].e-l[i].s; 96 dou len=dist(p); 97 p=p/len; 98 l[i].p=p; 99 } 100 std::sort(l+1,l+1+n,cmp); 101 int id=1; 102 l[1].id=1; 103 for (int i=2;i<=n;i++) 104 if (l[i].p!=l[i-1].p) 105 l[i].id=++id; 106 else 107 l[i].id=id; 108 for (int i=1;i<=n;i++) 109 for (int j=i+1;j<=n;j++) 110 if (LineIntersect(l[i],l[j])){ 111 Point p=inter(l[i],l[j]); 112 Point e1=l[i].e-l[i].s,e2=l[j].e-l[j].s; 113 dou len1=dist(e1),len2=dist(e2); 114 e1=e1/len1;e2=e2/len2; 115 dou x1=e1.x,x2=e2.x,y1=e1.y,y2=e2.y,z1=e1.z,z2=e2.z; 116 dou x=1; 117 dou y=(x2*z1-x1*z2)/(y1*z2-z1*y2); 118 dou z=(-x1*x-y1*y)/z1; 119 Point e=Point(x,y,z); 120 for (int k=1;k<=n;k++) tmp[k]=0; 121 tmp[l[i].id]=1;tmp[l[j].id]=1; 122 for (int k=1;k<=n;k++) 123 if (k!=i&&k!=j) 124 if (fabs((l[k].e-l[k].s)/e)<eps&&LineIntersect(l[i],l[k])) tmp[l[k].id]=1; 125 int cnt=0; 126 for (int k=1;k<=n;k++) if (tmp[k]) cnt++; 127 ans=std::max(ans,cnt); 128 cnt=2; 129 for (int k=1;k<=n;k++) 130 if (k!=i&&k!=j) 131 if ((inter(l[k],l[i])==p)) cnt++; 132 ans=std::max(ans,cnt); 133 } 134 printf("%d ",ans); 135 } 136 int main(){ 137 freopen("spider.txt","r",stdin); 138 n=read(); 139 for (int i=1;i<=n;i++){ 140 int kx=read(),bx=read(),ky=read(),by=read(); 141 Point p1,p2; 142 p1.x=-1;p1.y=-kx+bx;p1.z=-ky+by; 143 p2.x=1;p2.y=kx+bx;p2.z=ky+by; 144 l[i]=Line(p1,p2); 145 } 146 solve(); 147 }
只好改成std的写法了。
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #define sz 1020000 7 #define ll long long int 8 using namespace std; 9 int n,ans=1; 10 ll kx[sz],ky[sz],bx[sz],by[sz]; 11 int read(){ 12 int t=0,f=1;char ch=getchar(); 13 while (ch<'0'||ch>'9'){if (ch=='-')f=-1;ch=getchar();} 14 while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();} 15 return t*f; 16 } 17 ll gcd(ll a,ll b){ 18 if (b==0) return a; 19 else return gcd(b,a%b); 20 } 21 bool ok(ll i,ll j,ll &X,ll &Y,ll &T,ll &T2){ 22 if (kx[i] == kx[j]){ 23 if (ky[i] == ky[j]) return 0; 24 T = by[i] - by[j]; T2 = ky[j] - ky[i]; 25 } else{ 26 T = bx[i] - bx[j]; T2 = kx[j] - kx[i]; 27 } 28 if (kx[i] * T + bx[i] * T2 == kx[j] * T + bx[j] * T2 && 29 ky[i] * T + by[i] * T2 == ky[j] * T + by[j] * T2){ 30 X = kx[i] * T + bx[i] * T2; 31 Y = ky[i] * T + by[i] * T2; 32 ll g = gcd(gcd(X, Y), gcd(T, T2)); 33 X /= g; Y /= g; T /= g; T2 /= g; 34 35 return 1; 36 } else return 0; 37 } 38 void plane(ll i,ll j,ll &A,ll &B,ll &C,ll &D){ 39 if (bx[i]-bx[j]==0&&by[i]-by[j]==0){ 40 A=ky[i]-ky[j],B=kx[i]-kx[j]; 41 }else{ 42 A=by[i]-by[j],B=bx[i]-bx[j]; 43 } 44 C=A*kx[i]+B*ky[i]; 45 D=A*bx[i]+B*by[i]; 46 ll g=gcd(gcd(A,B),gcd(C,D)); 47 A/=g;B/=g;C/=g;D/=g; 48 } 49 class Hash{ 50 public: 51 ll F(ll a, ll b, ll c, ll d){ 52 ll s = (a * 3325443 + b * 3249082 + c * 2308478 + d * 2390850) % 3214567; 53 if (s < 0) s = -s; 54 return s; 55 } 56 ll node[3214567], next[sz], A[sz], B[sz], C[sz], D[sz], pass[sz]; 57 ll e; 58 void ins(ll a,ll b,ll c,ll d){ 59 ll s=F(a,b,c,d); 60 e++; 61 next[e]=node[s];node[s]=e; 62 A[e]=a;B[e]=b;C[e]=c;D[e]=d; 63 } 64 bool find(ll a,ll b,ll c,ll d){ 65 ll s=F(a,b,c,d),j; 66 for (j=node[s];j;j=next[j]){ 67 if (A[j]==a&&B[j]==b&&C[j]==c&&D[j]==d) 68 return 1; 69 } 70 return 0; 71 } 72 }Point,Plane,Slope; 73 int main(){ 74 freopen("spider.txt","r",stdin); 75 ll A,B,C,D; 76 n=read(); 77 for (int i=1;i<=n;i++) 78 kx[i]=read(),bx[i]=read(),ky[i]=read(),by[i]=read(); 79 for (int i=1;i<=n;i++) 80 for (int j=i+1;j<=n;j++) 81 if (ok((ll)i,(ll)j,A,B,C,D)){ 82 if (!Point.find(A,B,C,D)) Point.ins(A,B,C,D); 83 plane(i,j,A,B,C,D); 84 if (!Plane.find(A,B,C,D)) Plane.ins(A,B,C,D); 85 } 86 for (ll i=1;i<=Point.e;i++){ 87 for (ll a=1;a<=n;a++){ 88 if (kx[a]*Point.C[i]+bx[a]*Point.D[i]==Point.A[i]) 89 if (ky[a]*Point.C[i]+by[a]*Point.D[i]==Point.B[i]) 90 Point.pass[i]++; 91 } 92 } 93 for (ll i=1;i<=Plane.e;i++){ 94 for (ll a=1;a<=n;a++){ 95 if (kx[a] * Plane.A[i] + ky[a] * Plane.B[i] == Plane.C[i]) 96 if (bx[a] * Plane.A[i] + by[a] * Plane.B[i] == Plane.D[i]) 97 if (!Slope.find(kx[a],ky[a],i,0)){ 98 Plane.pass[i]++; 99 Slope.ins(kx[a],ky[a],i,0); 100 } 101 } 102 } 103 for (int i=1;i<=Point.e;i++) 104 if (Point.pass[i]>ans) ans=Point.pass[i]; 105 for (int i=1;i<=Plane.e;i++) 106 if (Plane.pass[i]>ans) ans=Plane.pass[i]; 107 printf("%d ",ans); 108 }