B Boundary(由弦求圆)

题:https://ac.nowcoder.com/acm/contest/5667/B

题意:给出n个二维平面点,问最多有多少个点和原点(0,0)同时在同一个圆的边上

分析:由三点确定圆心n^2枚举出所有圆心,最后求众数即可;

   由于我们n^2枚举出来的圆心个数是由重复部分的,因为假设1,2,3,4点在同一个圆x上,而我们枚举1 时x的圆心的贡献是3,而枚举2时x的圆心贡献是2,以此类推就是一个1~n的和,所以只要排序后累计个数即可

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define MP make_pair
#define eps 1e-10
typedef long long ll;
const int mod=1e9+7;
const int M=2e5+5;
const int N=2e6+6;
const int inf=0x3f3f3f3f;
const ll INF=1e18;
struct node{
    double x,y;
    node(double X=0,double Y=0):x(X),y(Y){};
}p[M],b[N];
double X,Y,R;
//过三点求圆心坐标
node waixin(node a,node b,node c){
    double a1 = b.x - a.x, b1 = b.y - a.y, c1 = (a1*a1 + b1*b1)/2;
    double a2 = c.x - a.x, b2 = c.y - a.y, c2 = (a2*a2 + b2*b2)/2;
    double d = a1*b2 - a2*b1;
    return node(a.x + (c1*b2 - c2*b1)/d, a.y + (a1*c2 -a2*c1)/d);
}
int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%lf%lf",&p[i].x,&p[i].y);
    node O={0,0};
    int tot=0;
    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++){
            if(fabs(p[i].x*p[j].y-p[j].x*p[i].y)>eps){
                node tmp=waixin(p[i],p[j],O);
                b[tot++]=tmp;
            }
        }
    if(tot==0)
        return printf("1"),0;
    sort(b,b+tot,[&](node A,node B){
        if(fabs(A.x-B.x)<eps)
            return A.y-B.y<eps;
        else
            return A.x-B.x<eps;
    });
    int countt=1,maxx=1;
    for(int i=0;i<tot-1;i++)
        if(fabs(b[i].x-b[i+1].x)<eps&&fabs(b[i].y-b[i+1].y)<eps)
            countt++,maxx=max(maxx,countt);
        else
            countt=1;
    int sum=maxx*2;
    for(int i=1;i<=n;i++)
        if(i*(i-1)==sum)
            return printf("%d",i),0;
    return 0;
}
View Code

 

posted @ 2020-07-14 13:33  starve_to_death  阅读(171)  评论(0编辑  收藏  举报