2020 Niuke Summer School Second B-Boundary

For the title, click here
to give you a two-dimensional plane plus n (n<2000) points, and ask you how many points you can find to be in a circle with the origin (0,0).
Wrong idea: In the beginning, I wanted to enumerate a point as the diameter, and then find the point that can form a right angle with the diameter in the remaining points. However, points that are co-circular do not necessarily have points that can form a diameter, so consideration is not complete.
Correct method:
1. You can use the angle of the circle to find the same as the problem solution.
2. Find two points at random, connect them to the origin, and then make a vertical line on the connected straight line. The intersection of the two vertical lines is the center of the circle. , And finally judge which point becomes the center of the circle the most times is the origin we are looking for, and then judge the maximum number of n (that is, we finally get the answer) to find two points to meet the requirements.

The process of finding the center of a circle is to solve a system of equations:

Insert picture description here
Reference: https://blog.csdn.net/weixin_43269437/article/details/107327887?%3E

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 2e3+7;
vector< pair<int,int> >P;//点 
vector< pair<double,double> >C;//可能的圆心 

ll getD(ll a,ll b,ll c,ll d){
    
    
	return a*d-b*c;
}
 
int main()
{
    
    
	int n;
	P.resize(2007);
	scanf("%d",&n);
	int x,y;
	for(int i = 1;i <= n;i ++){
    
    
		scanf("%d%d",&x,&y);
		P[i] = make_pair(x,y);//存对用make_pair 
	}
	for(int i = 1;i <= n-1;i ++){
    
    
		for(int j = i+1;j <= n;j ++){
    
    
			int x1 = P[i].first,y1 = P[i].second;
			int x2 = P[j].first,y2 = P[j].second;
			// 克拉默法则解方程组 
			ll a11 = 2*x1,a12 = 2*y1,b1 = x1*x1+y1*y1;
			ll a21 = 2*x2,a22 = 2*y2,b2 = x2*x2+y2*y2;
			ll D = getD(a11,a12,a21,a22);
			if(D == 0) continue;
			ll D1 = getD(b1,a12,b2,a22);
			ll D2 = getD(a11,b1,a21,b2);
			//printf("%d %d %d\n",D,D1,D2);
			C.push_back(make_pair((double)D1/D , (double)D2/D ));//圆心可能的解 
		}
	}
	sort(C.begin(),C.end());
	int maxx = 0;
	for(int i = 0;i < C.size();){
    
    
		int j = i;
		while(j < C.size()&&C[j] == C[i]) j++;
		maxx = max(maxx,j-i);
		i = j;
	}
	//cout<<maxx<<endl; 
	int ans = 0;
	for(int i = 1;i < MAXN;i ++){
    
    
		if((i-1)*i/2 <= maxx)//这个n可能是合法的点的个数
			ans = max(ans,i); 
	}
	printf("%d\n",ans);
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_45672411/article/details/107381240