FJ省队集训DAY2 T1

思路:转换成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\n",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\n",ans);  
108 }

 

posted @ 2016-07-04 21:05  GFY  阅读(307)  评论(0编辑  收藏  举报