原题题面
Given points in 2D plane. Considering all circles that the origin point 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 , denoting the number of given points.
Following {n}n lines each contains two integers x, y$ (∣x∣,∣y∣≤10000)$, denoting a given point .
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.
输入样例
4
1 1
0 2
2 0
2 2
输出样例
3
题面解析
首先很容易就能想到
的暴力方法,但显然会超时。
先放出题人的方法,出题人给出了圆周角的方法计算(下图)
笔者自己实际去尝试了以下,发现有部分细节并未说清楚(多个点平行时的处理),故不提供该种解法的代码。
笔者采用中垂线的办法去计算。
先算枚举两个点做两条中垂线,算完交点后取出最多的那个就是答案。
所以只要两重循环开
的复杂度去枚举点,然后用pair和map存下每个点出现的次数并比较即可。
需要注意的是,这题似乎卡了精度,貌似1e-10是可以的,读者可以自行尝试。
AC代码(345ms)
#include<bits/stdc++.h>
using namespace std;
double eps=1e-10;
typedef pair<double, double> Pair;
int epsCmp(double x, double y)//误差范围内相等
{
if (fabs(x-y)<eps)
return 0;
if (x>y)
return 1;
return -1;
}
struct point
{
double x;
double y;
};
struct line//ax+by+c=0
{
double a;
double b;
double c;
};
point points[2010];
map<Pair,long long> hashMap;
void solve1()
{
int t;
scanf("%d", &t);
for(int i=1; i<=t; i++)
{
scanf("%lf %lf", &points[i].x, &points[i].y);
}
long long ans=0;//初值不能是1,因为可能会出现n=1的情况
for(int i=1; i<=t-1; i++)
{
hashMap.clear();
for(int j=i+1; j<=t; j++)
{
point O=point{0.0, 0.0};//原点
point P=point{points[i].x, points[i].y};//第一个枚举点P
point A=point{points[j].x, points[j].y};//第二个枚举点A
line OP=line{P.x, P.y, -(P.x*P.x+P.y*P.y)/2.0};//OP中垂线
line OA=line{A.x, A.y, -(A.x*A.x+A.y*A.y)/2.0};//OA中垂线
if (epsCmp(AP.a*OP.b, AP.b*OP.a)!=0)//排除平行情况
{
double x0=(OP.b*AP.c-OP.c*AP.b)/(OP.a*AP.b-OP.b*AP.a);
double y0=(OP.a*AP.c-OP.c*AP.a)/(OP.a*AP.b-OP.b*AP.a);
ans=max(ans, ++hashMap[Pair(x0,y0)]);//比较结果
}
}
}
printf("%lld\n", ans+1);//有n个圆形相同就有n+1个点被覆盖
}
int main()
{
// ios_base::sync_with_stdio(false);
// cin.tie(0);
// cout.tie(0);
#ifdef ACM_LOCAL
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
long long test_index_for_debug=1;
char acm_local_for_debug;
while(cin>>acm_local_for_debug)
{
cin.putback(acm_local_for_debug);
if (test_index_for_debug>100)
{
throw runtime_error("Check the stdin!!!");
}
auto start_clock_for_debug=clock();
solve1();
auto end_clock_for_debug=clock();
cout<<"\nTest "<<test_index_for_debug<<" successful"<<endl;
cerr<<"Test "<<test_index_for_debug++<<" Run Time: "
<<double(end_clock_for_debug-start_clock_for_debug)/CLOCKS_PER_SEC<<"s"<<endl;
cout<<"--------------------------------------------------"<<endl;
}
#else
solve1();
#endif
return 0;
}
后记
赛后被学弟带飞,不愧是后浪拍死前浪…
DrGilbert 2020.7.13