ZCC loves star

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;
}

 

posted @ 2018-02-04 12:34  泪寒之雪  阅读(237)  评论(0编辑  收藏  举报