1. 程式人生 > 實用技巧 >2020牛客多校第二場B題Boundary(三角形外心計算幾何)

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:根據方程推導,列舉兩個點也可以求出圓心。

#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; }
View Code