2020牛客暑期多校第二场 B - Boundary(简单计算几何)

传送门


题解这样说:
2020牛客暑期多校第二场 B - Boundary(简单计算几何)_第1张图片
但是我这样写了却过不了,可能是计算角度时浮点数的误差太大了,实际上主流的做法并不是从圆心角下手,而是根据三点共圆,因为必过原点,那么只需枚举另外的两个点,计算出圆心坐标,然后使用 m a p map map统计每次枚举有多少相同的圆心坐标

关于三点共圆求圆心,可以参考这里

#include <set>
#include <map>
#include <stack>
#include <queue>
#include <math.h>
#include <cstdio>
#include <string>
#include <bitset>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std;
#define fi first
#define se second
#define Vector Point
#define pb push_back
#define ins insert
#define lowbit(x) (x&(-x))
#define mkp(x,y) make_pair(x,y)
#define mem(a,x) memset(a,x,sizeof a);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int,int> P;
typedef pair<double,double> pdd;
const double eps=1e-8;
const double pi=acos(-1.0);
const int inf=0x3f3f3f3f;
const ll INF=1e18;
const int Mod=1e9+7;
const int maxn=2e5+10;

inline int dcmp(double d){
	if(fabs(d)<eps) return 0;
	return d>0?1:-1;
}

inline int cmp(double x,double y){
	return dcmp(x-y);
}

struct Point{
    double x,y;
    Point(double a=0,double b=0):x(a),y(b){}

    Vector operator + (Vector B){
        return Vector(x+B.x,y+B.y);
    }

    Vector operator - (Point B){
        return Vector(x-B.x,y-B.y);
    }

    Vector operator * (double d){  //数乘
        return Vector(x*d,y*d);
    }

    double operator * (Vector B){  //数量积
        return x*B.x+y*B.y;
    }

    Vector operator / (double d){
        return Vector(x/d,y/d);
    }

    double operator ^ (Vector B){  //叉乘
        return x*B.y-y*B.x;
    }

    bool operator < (const Point &b) const {
        if(dcmp(x-b.x)==0) return y<b.y;
        return x<b.x;
    }

    bool operator == (const Point& b) const {
        if(dcmp(x-b.x)==0 && dcmp(y-b.y)==0)
            return true;
        return false;
    }
}p[2020];


map<pdd,int> mp;

pdd getCircleCenter(Point a,Point b,Point c){
    double x=((a.x*a.x+a.y*a.y)*(b.y-c.y)+(b.x*b.x+b.y*b.y)*(c.y-a.y)+(c.x*c.x+c.y*c.y)*(a.y-b.y)) / (2.0*(a.x*(b.y-c.y)-a.y*(b.x-c.x)+b.x*c.y-c.x*b.y));
    double y=((a.x*a.x+a.y*a.y)*(c.x-b.x)+(b.x*b.x+b.y*b.y)*(a.x-c.x)+(c.x*c.x+c.y*c.y)*(b.x-a.x)) / (2.0*(a.x*(b.y-c.y)-a.y*(b.x-c.x)+b.x*c.y-c.x*b.y));
    return make_pair(x,y);
}

int main(){
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    //ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%lf%lf",&p[i].x,&p[i].y);
    Point o=Point(0,0);
    int ans=0;
    for(int i=0;i<n;i++){
        mp.clear();
        for(int j=i+1;j<n;j++){
            if(dcmp(p[i]^p[j])==0) continue;
            pdd cur=getCircleCenter(o,p[i],p[j]);
            mp[cur]++;
            ans=max(ans, mp[cur]);
        }
    }
    printf("%d\n",ans+1);
    return 0;
}

你可能感兴趣的:(牛客比赛)