ZCC夜观星象,企图找到宇宙的中心。根据某种伪科学思想,宇宙中心可以用 这种方法找到:把夜空中的星星两两分组,连接同组中的两颗星星,如果所 有组都交于同个点,且两两组之间仅有1个交点,那么这个交点就是宇宙的 中心了。可是分组的方法实在太多了,ZCC想要知道宇宙的中心到底在哪。
本题有多组数据。 第一个为数组组数T。 对于每组数据,第1行包含1个整数 n,表示星星的对数。 接下来的2n行,每行包含两个实数x_i,y_i,表示第i个星 星的坐标
对于每组数据,如果没有中心,输出"None",如果存在多个中心,输出"So many",否则输出"Find (x,y)",(x,y)为中心的坐标。保留8位实数。
对于100%的数据:T<=3,n<=70。
SOL:
我们发现每对都要交于一点,那么我们发现我们可以任意取2个点,再枚举两个点,互相连线就是所有可能的中心,那我们以此中点判一下是否合法就好了。
#pragma GCC optimize("-Ofast") #include<bits/stdc++.h> #define sight(c) (‘0‘<=c&&c<=‘9‘) #define LL long long #define deg printf #define dput put #define dputc putchar #define N 147 #define esp 1e-6 #define inf 1e9 #define db long double #define eho(x) for(int i=head[x];i;i=net[i]) db a[N],b[N],k1,k2,b1,b2,XX,YY,as,bs,ans; int n,T; struct po{ db x,y; po(){} po(db aa,db bb):x(aa),y(bb){} inline db operator *(const po& A)const{return x*A.y-y*A.x;} inline bool operator <(const po& A)const{ return x*A.y-y*A.x<-esp; } inline int ord() { if (x<esp&&-esp<x) return 0; return atanl(y/x)*400000; } }p[N]; inline void read(int &x){ static char c; for (c=getchar();!sight(c);c=getchar()); for (x=0;sight(c);c=getchar())x=x*10+c-48; } void write(int x){if (x<10) {putchar(‘0‘+x); return;} write(x/10); putchar(‘0‘+x%10);} inline void writeln(int x){ if (x<0) putchar(‘-‘),x*=-1; write(x); putchar(‘\n‘); } inline void writel(int x){ if (x<0) putchar(‘-‘),x*=-1; write(x); putchar(‘ ‘); } using namespace std; int ap,t,tl,ff,ttt; struct Point{db x,y;}pp[N]; struct stline{Point a,b;} line1,line2; int dblcmp(db a,db b){ if (fabs(a-b)<=esp) return 0; if (a>b) return 1; else return -1;} inline db dot(db x1,db y1,db x2,db y2) { return x1*x2+y1*y2; } int point_on_line(Point a,Point b,Point c) { return dblcmp(dot(b.x-a.x,b.y-a.y,c.x-a.x,c.y-a.y),0);} double cross(double x1,double y1,double x2,double y2){ return x1*y2-x2*y1; } double ab_cross_ac(Point a,Point b,Point c) { return cross(b.x-a.x,b.y-a.y,c.x-a.x,c.y-a.y); } Point xxx; int ab_cross_cd (Point& a,Point& b,Point& c,Point& d) { xxx.x=-inf; xxx.y=-inf; db s1,s2,s3,s4; int d1,d2,d3,d4; d1=dblcmp(s1=ab_cross_ac(a,b,c),0); d2=dblcmp(s2=ab_cross_ac(a,b,d),0); d3=dblcmp(s3=ab_cross_ac(c,d,a),0); d4=dblcmp(s4=ab_cross_ac(c,d,b),0); if (dblcmp((a.x-b.x)*(c.y-d.y)-(c.x-d.x)*(a.y-b.y),0)==0) return -1; xxx.x=(c.x*s2-d.x*s1)/(s2-s1); xxx.y=(c.y*s2-d.y*s1)/(s2-s1); return 1; } //mp<LL,> short g[1600000],*mp=g+800003; //inline void getk(int x,int y,db &k,db &bb) {k=(b[x]-b[y])/(a[x]-a[y]); bb=(a[x]*b[y]-a[y]*b[x])/(a[x]-a[y]);} void jiao(int x1,int y1,int x2,int y2) { ttt=ab_cross_cd(pp[x1],pp[y1],pp[x2],pp[y2]); if (ttt<0) return; XX=xxx.x; YY=xxx.y; for (int i=1;i<=2*n;i++) p[i]=po(a[i]-XX,b[i]-YY); ap=0; for (int i=1;i<=2*n;i++) { ff=p[i].ord(); t=mp[ff]; if (t>1) { for (int j=1;j<=i;j++) mp[p[j].ord()]=0; return; } tl=t^1; ap=ap+tl-t; mp[ff]=t+1; } for (int i=2*n;i;i--) { ff=p[i].ord(); mp[ff]=0; } if (ap) return; if (abs(as-XX)<esp&&abs(bs-YY)<esp) return; as=XX,bs=YY,ans++; cerr<<x1<<‘ ‘<<y1<<‘ ‘<<x2<<‘ ‘<<y2<<‘ ‘<<as<<‘ ‘<<bs<<endl; } signed main() { freopen("star.in","r",stdin); freopen("star.out","w",stdout); read(T); while (T--) { read(n); ans=0;as=-inf;bs=-inf; for (int i=1;i<=2*n;i++) scanf("%Lf %Lf",a+i,b+i),pp[i].x=a[i],pp[i].y=b[i]; for (int i=3;i<=2*n;i++) for (int j=3;j<=2*n;j++) if (i^j) { jiao(1,i,2,j), jiao(1,2,i,j); if (ans>1) { puts("So many"); goto a;} } a: if (ans>1) continue; if (!ans) puts("None"); if (ans==1) if (as<=0&&as+esp>0) printf("Find (0.00000000,%.8Lf)\n",as,bs); else printf("Find (%.8Lf,%.8Lf)\n",as,bs); } return 0; }