2020牛客暑期多校训练营 第二场 B Boundary 计算几何 圆 已知三点求圆心

LINK:Boundary

计算几何确实是弱项 因为好多东西都不太会求 没有到很精通的地步。

做法很多,先说官方题解

其实就是枚举一个点 P 然后可以发现 再枚举一个点 然后再判断有多少个点在圆上显然会超时。

直接考虑求出所有点和(O,P)的夹角 因为同弧所对圆周角相等 最后统计有多少个角度相等来做。

一个误区是 两个对称的圆上的点被算在一起了 此时强制利用 第三个点在所在直线的左侧/右侧来消除影响。

正确性显然。复杂度(n^2cdot logn)

一个比较好想好写的做法:

枚举到第三个点的时候就不能再统计有多少个点在这个圆上了 然后 考虑答案的圆的圆心一定是被重复计算出次数最多的。

所以可以得到某个圆心被计算次数最多的数量 反推出点数即可。

一个难点 已知三点求圆心 这好像是一个模板 不过推导需要利用 克莱姆法则及矩阵行列式的知识来推 这我肯定式推不出来滴 而且公式挺难背的!~

code
//#include<bitsstdc++.h>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 10000000000000000ll
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define gt(x) scanf("%d",&x)
#define gi(x) scanf("%lf",&x)
#define put(x) printf("%d
",x)
#define putl(x) printf("%lld
",x)
#define gc(a) scanf("%s",a+1)
#define rep(p,n,i) for(RE int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define fep(n,p,i) for(RE int i=n;i>=p;--i)
#define vep(p,n,i) for(RE int i=p;i<n;++i)
#define pii pair<int,int>
#define mk make_pair
#define RE register
#define P 1000000007
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define EPS 1e-6
#define sq sqrt
#define S second
#define F first
#define mod 1000000007
#define V vector
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc()
{
    return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline int read()
{
    RE int x=0,f=1;RE char ch=getc();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
    return x*f;
}
const int MAXN=2010;
int n,flag;db w1,w2;
struct wy
{
	db x,y;
}t[MAXN];
V<pair<db,db> >g;
int pd(db x,db y){return fabs(x-y)<=EPS;}
inline void calc(wy a,wy b,wy c)
{
	flag=0;
	db D1=2*(a.y-c.y)*(a.x-b.x)-2*(a.y-b.y)*(a.x-c.x);
	db D2=2*(a.y-b.y)*(a.x-c.x)-2*(a.y-c.y)*(a.x-b.x);
	if(pd(D1,0)||pd(D2,0)){flag=1;return;}
	db W1=pf(a.x)-pf(b.x)+pf(a.y)-pf(b.y);
	db W2=pf(a.x)-pf(c.x)+pf(a.y)-pf(c.y);
	w1=(W1*(a.y-c.y)-W2*(a.y-b.y))/D1;
	w2=(W1*(a.x-c.x)-W2*(a.x-b.x))/D2;
}
int main()
{
	//freopen("1.in","r",stdin);
	get(n);
	rep(1,n,i)get(t[i].x),get(t[i].y);
	rep(1,n,i)rep(i+1,n,j)
	{
		calc((wy){0,0},t[i],t[j]);
		if(flag)continue;
		g.pb(mk(w1,w2));
	}
	if(g.size()==0){puts("1");return 0;}
	sort(g.begin(),g.end());
	int mx=1,cnt=1;pair<db,db>ww=g[0];
	vep(1,g.size(),i)
	{
		if(pd(ww.F,g[i].F)&&pd(ww.S,g[i].S))++cnt,mx=max(mx,cnt);
		else ww=g[i],cnt=1;
	}
	int cc=(1+(int)sqrt(1+1.0*8*mx))/2;
	put(cc);return 0;
}
原文地址:https://www.cnblogs.com/chdy/p/13300161.html