2020牛客多校第二场B题Boundary(三角形外心计算几何)
题目链接 https://ac.nowcoder.com/acm/contest/5667/B
题意:给你n个二维坐标,设计一个圆过(0,0),输出 圆经过的坐标数量最多多少个
题解1:枚举2个点和(0,0) 三点求三角形的外心即过三点的圆心。重复次数最多的即为答案的圆心
输出的答案是根据在圆上的点组成的多边形的边数即为(ans*2 一个三角形两条边)求的,得到边数后求(int)sqrt(ans*2) +1就是答案。
也可以这样想
在暴力枚举的两个点中,我们是组合数进行选取的,也就是n个点选取2个
C(2,n)=n*(n-1)/2=max
其中max是指出现最多的圆心坐标的次数
那么直接枚举1到n满足上述式子的就是答案
也就是(int)sqrt(ans*2)+1
题解2:根据方程推导,枚举两个点也可以求出圆心。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #include <bits/stdc++.h> #define inf 0x3f3f3f3f using namespace std; typedef long long ll; const int maxn=2e3+7; const ll mod =1e9+7; typedef pair<int,int> pii; typedef pair<double,double> pdd; vector<pdd> v; struct point{ ll x,y; }a[maxn]; //求三角形外心 void getc(const point& p1, const point& p2, const point& p3, pdd& center) { ll x1 = p1.x; ll x2 = p2.x; ll x3 = p3.x; ll y1 = p1.y; ll y2 = p2.y; ll y3 = p3.y; ll t1=x1*x1+y1*y1; ll t2=x2*x2+y2*y2; ll t3=x3*x3+y3*y3; double temp=x1*y2+x2*y3+x3*y1-x1*y3-x2*y1-x3*y2; center.first = double(t2*y3+t1*y2+t3*y1-t2*y1-t3*y2-t1*y3)/temp; center.second = double(t3*x2+t2*x1+t1*x3-t1*x2-t2*x3-t3*x1)/temp; } int main(){ IOS int n; cin>>n; for(int i=0;i<n;i++){ cin>>a[i].x>>a[i].y; } point temp; temp.x=0,temp.y=0; for(int i=0;i<n-1;i++){ for(int j=i+1;j<n;j++){ pdd c; if(a[i].x*a[j].y!= a[i].y*a[j].x){ getc(a[i],a[j],temp,c); v.push_back(c); } } } sort(v.begin(),v.end()); int ans=0,cnt=0; pdd tmp=v[0]; for(auto i: v ){ if(i==tmp){ cnt++; }else{ ans=max(ans,cnt); cnt=1; tmp=i; } } ans=max(cnt,ans); for (int i = 1; i <= n; i++){ if (i * (i - 1) == ans* 2){ printf("%d", i); return 0; } } //cout<<int(sqrt(ans*2))+1<<endl; return 0; }