1. 程式人生 > 實用技巧 >2020牛客暑期多校訓練營(第二場)[ Boundary]

2020牛客暑期多校訓練營(第二場)[ Boundary]

2020牛客暑期多校訓練營(第二場) Boundary

題目大意:

給你n個點,問最多有多少個點在同一個圓的邊界,要求原點也必須在這個圓上。

題解:

這個題目我就是看的題解寫的,所以直接看題解吧。【題解】2020牛客暑假多校訓練營(第二場)

需要注意的就是 判斷角度是否一樣需要用 \(fabs(x-y)<eps\) 這個\(eps=1e-10\) 這樣才能過,如果 \(eps=1e-6\) 只能過 \(85\%\) ,如果 \(eps=1e-8\) 只能過 \(90\%\)

#include <bits/stdc++.h>
#define debug(x) printf("debug:%s=%d\n",#x,x);
//#define debug(x) cout << #x << ": " << x << endl
using namespace std;
const int maxn = 2e3+10;
const double eps = 1e-10;
typedef long long ll;
ll x[maxn],y[maxn];
double ans[maxn];
 
double getLen(int i,int j){
    double res = (x[j]-x[i])*(x[j]-x[i])+(y[j]-y[i])*(y[j]-y[i]);
    return sqrt(res);
}
 
double getCos(int i,int j,int k){
    double c = getLen(i,j);
    double a = getLen(j,k);
    double b = getLen(i,k);
    return acos((a*a+b*b-c*c)/(2*a*b));
}
 
int main(){
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%lld%lld",&x[i],&y[i]);
    x[0]=y[0]=0;
    int sum = 1;
    for(int i=1;i<=n;i++) {
        int now = 0;
        for (int j = 1; j <= n; j++) {
            ll num = x[i] * y[j] - x[j] * y[i];
            if (num >= 0) continue;
            double res = getCos(0, i, j);
//            printf("i=%d j=%d res=%f\n",i,j,res);
            ans[++now] = res;
        }
        int cnt = 2;
        if (now) {
            sum = max(sum, 2);
            sort(ans + 1, ans + 1 + now);
            for (int j = 2; j <= now; j++) {
                if (ans[j] - ans[j - 1] < eps) {
                    cnt++, sum = max(sum, cnt);
                } else cnt = 2;
            }
        }
    }
    printf("%d\n",sum);
}
 
/*
5
3 3
8 6
8 8
1 3
4 2
 
 
 
*/