欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Boundary

程序员文章站 2022-03-02 10:54:30
...

链接:https://ac.nowcoder.com/acm/contest/5667/B
来源:牛客网

题目描述

Given n{n}n points in 2D plane. Considering all circles that the origin point (0,0){(0, 0)}(0,0) is on their boundries, find the one with the maximum given points on its boundry. Print the maximum number of points.

输入描述:

The first line contains one integer n (1≤n≤2000)n~(1 \leq n \leq 2000)n (1≤n≤2000), denoting the number of given points.
Following n{n}n lines each contains two integers x,y (∣x∣,∣y∣≤10000)x, y~(|x|,|y| \leq 10000)x,y (∣x∣,∣y∣≤10000), denoting a given point (x,y){(x, y)}(x,y).
It's guaranteed that the points are pairwise different and no given point is the origin point.

输出描述:

Only one line containing one integer, denoting the answer.

示例1

输入

复制 4 1 1 0 2 2 0 2 2

4
1 1
0 2
2 0
2 2

输出

复制 3

3

说明

Considering circle (x−1)2+(y−1)2=2(x-1)^2+(y-1)^2=2(x−1)2+(y−1)2=2, we can see that the origin point is on its boundry and that there are 3 given points (0,2),(2,0),(2,2){(0,2),(2,0),(2,2)}(0,2),(2,0),(2,2) on its boundry.

题意: 原点默认, 给你一堆点。 然后画出的圆肯定要过原点,

思路:因为三点确定圆(这里我是去网上找板子的,因为之前就做计算几何的题), 所以枚举两个点。然后记录所有的圆心。

TLE:如果对所有圆心去看剩下的所有点是不是满足改圆心的半径,那么一共是O(n^3)的

优化:比如我们有四个点在一个圆上,那么因为题目给了原点,所以我们任取另外两个点就能形成这个圆,但是同时,虽然枚举的两点不同,最后出来的却是一个圆心,也就是说在这个情况下,我们算出来有C(4个取2个)的那么多相同的圆心。那假如有M个在一个圆上,我们sort一遍,然后统计圆心重合最多的时候数量是多少个(假如ans个)。然后再看哪个数能满足C(m个取2个)==ans;即答案

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=2e3+10;
typedef long long LL;
double getx(double x1,double y1,double x2,double y2,double x3,double y3)
{
    double a=((y2-y1)*(y3*y3-y1*y1+x3*x3-x1*x1)-(y3-y1)*(y2*y2-y1*y1+x2*x2-x1*x1))/(2.0*((x3-x1)*(y2-y1)-(x2-x1)*(y3-y1)));
    return a;
}
double gety(double x1,double y1,double x2,double y2,double x3,double y3)
{
    double b=((x2-x1)*(x3*x3-x1*x1+y3*y3-y1*y1)-(x3-x1)*(x2*x2-x1*x1+y2*y2-y1*y1))/(2.0*((y3-y1)*(x2-x1)-(y2-y1)*(x3-x1)));
    return b;
}
double x[maxn],y[maxn];
vector< pair<double,double> >v;
int main(void)
{
  cin.tie(0);std::ios::sync_with_stdio(false);
  LL n;cin>>n;
  for(LL i=1;i<=n;i++) cin>>x[i]>>y[i];
  for(LL i=1;i<n;i++)
  {
    for(LL j=i+1;j<=n;j++)
    {
        if(y[i]*x[j]==y[j]*x[i]) continue;//三点共线 
        double a=getx(0.0,0.0,x[i],y[i],x[j],y[j]);
        double b=gety(0.0,0.0,x[i],y[i],x[j],y[j]);
        double r=sqrt(a*a+b*b);
        
        v.push_back(make_pair(a,b));
    }
  }
  sort(v.begin(),v.end());

  if(v.size()==0)
  {
  	cout<<1<<endl;return 0;
  }
  LL sum=1; LL ans=1;
  for(int i=0;i<v.size();++i)
  {	
	double a=v[i].first;
    double b=v[i].second;
    double c=v[i+1].first;
    double d=v[i+1].second;
    if(fabs(c-a<1e-10&&fabs(d-b)<1e-10)) sum++,ans=max(sum,ans);
	else sum=1; 
  } 
 for(LL i=1;i<=n ;i++)
 {
 	if(i*(i-1)==2*ans)  	
	 {
	 	cout<<i<<endl;
	 	break;
	 }
 }
return 0;
}
相关标签: 计算几何