2020牛客暑期多校训练营(第二场)——B

2020牛客暑期多校训练营(第二场)——B_第1张图片
题意:给定n个点,让更多的点落在同一个经过原点(0,0)的圆上,求出最多的点数。
题解:固定一个点,再遍历一遍其他点,加上原点,每次三个点,可以确定一个圆,手动推出圆心坐标的公式,然后遍历出有多少个点落在这个圆上,求出最大值即可。
推圆心坐标:两点确定一条直线,三点求出两条直线,再求出这两条直线的垂线,再求出两条直线的交点即可。
2020牛客暑期多校训练营(第二场)——B_第2张图片

#include
using namespace std;
typedef long long ll;
typedef pair<double,double>P;
const int N=2050;
ll x[N],y[N];
map<P,int>mp;
int n;
bool check(ll x1,ll y1,ll x2,ll y2) {
	return 1ll*x1*y2==1ll*x2*y1;
}
void solve() {
	int ans=0;
	for(int i=1; i<=n; ++i) {
		mp.clear();
		for(int j=i+1; j<=n; ++j) {
			if(check(x[i],y[i],x[j],y[j]))continue;
			ll k=y[i]*(x[j]*x[j]+y[j]*y[j])-y[j]*(x[i]*x[i]+y[i]*y[i]);
			ll K=y[i]*x[j]-y[j]*x[i];
			ll l=x[i]*(x[j]*x[j]+y[j]*y[j])-x[j]*(x[i]*x[i]+y[i]*y[i]);
			ll L=y[j]*x[i]-y[i]*x[j];
			ans=max(ans,++mp[P(1.0*k/K,1.0*l/L)]);
		}
	}
	printf("%d\n",ans+1);
	return;
}
int main() {
	scanf("%d",&n);
	for(int i=1; i<=n; ++i) {
		scanf("%lld %lld",&x[i],&y[i]);
	}
	solve();
	return 0;
}

今天又是自闭的一天,排名不佳。
比赛的时候,认为计算坐标需要进行除法,会遇到精度不够的问题,没有敢写。下次一定要猛一猛。

你可能感兴趣的:(几何)