zoukankan      html  css  js  c++  java
  • 2020牛客暑期多校训练营(第二场)B

    题目链接:Boundary

    题意:给你n个点,问最多有多少个点与原点(0,0)在同一个圆上

    思路:由于三点确定一个圆,所以如果枚举剩余的两个点,然后再枚举其他点是否在圆上,那么复杂度为$O(n^3)$,会TLE

    但我们可以利用$“$同弧所对的圆周角相等$”$这一性质,所以可以先枚举一个点P,然后枚举其他的点A,计算$angle OAP$,找到这些角里面角的众数即可,但是角相等只能说明弧相等,并不能保证这两段弧为同一段弧,例如下图,$angle OA_{1}P=angle OA_{2}P$,但这两段弧并不是同一段弧

    我们只需要计算一边,所以用叉积来判断即可,既满足$vec{OP} imes vec{OA}<0$或者$vec{OP} imes vec{OA}>0$

    另一种方法:枚举两个点A,B,找到OA和AB中垂线的交点,这个交点就是圆心,计算圆心的众数即可,复杂度$O(n^2)$

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    
    using namespace std;
    
    const int N = 2010;
    const double eps = 1e-10;
    
    struct Vector {
        double x, y;
        Vector() { }
        Vector(double tx, double ty) : x(tx), y(ty) { }
    };
    
    int n;
    pair<double, double> p[N];
    double a[N], t;
    
    inline double dot(Vector a, Vector b)
    {
        return a.x * b.x + a.y * b.y;
    }
    
    inline double cross(Vector a, Vector b)
    {
        return a.x * b.y - a.y * b.x;
    }
    
    inline double calc(Vector a, Vector b)
    {
        double la = sqrt(a.x * a.x + a.y * a.y);
        double lb = sqrt(b.x * b.x + b.y * b.y);
        return acos(dot(a, b) / (la * lb));
    }
    
    int main()
    {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) scanf("%lf%lf", &p[i].first, &p[i].second);
        int res = 0, cnt = 0;
        for (int i = 1; i <= n; i++) {
            cnt = 0;
            for (int k = 1; k <= n; k++) {
                Vector op = Vector(p[i].first, p[i].second);
                Vector oa = Vector(p[k].first, p[k].second);
                Vector ap = Vector(p[k].first - p[i].first, p[k].second - p[i].second);
                Vector ao = Vector(p[k].first, p[k].second);
                if (cross(op, oa) < 0) a[++cnt] = calc(ap, ao);
            }
            sort(a + 1, a + cnt + 1);
            int imax = 0, c = 0;
            for (int i = 1; i <= cnt; i++) {
                if (fabs(a[i] - t) < eps) c++;
                else {
                    c = 1;
                    t = a[i];
                }
                imax = max(imax, c);
            }
            res = max(imax, res);
        }
        printf("%d
    ", res + 1);
        return 0;
    }
  • 相关阅读:
    Python assert(断言)
    Python importlib(动态导入模块)
    Python 异常处理
    Qt Clipboard剪贴板简单使用
    Qt5 QTableWidget设置列表自动适应列宽
    Fix VNC Desktop Sharing on Ubuntu Desktop 14.04
    Golang 交叉编译
    stdobj to array php
    Elasticsearch-集群原理
    Elasticsearch-基本操作2
  • 原文地址:https://www.cnblogs.com/zzzzzzy/p/13296282.html
Copyright © 2011-2022 走看看