生活随笔
收集整理的這篇文章主要介紹了
牛客多校2 - Boundary(几何)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:點擊查看
題目大意:給出 n 個點,需要我們選擇一個經過原點的圓,使得這個圓經過盡可能多的點,輸出最多可以經過多少個點
題目分析:n 的大小是 2000 ,顯然支持 n * n 最多再加一個 log 的寫法,因為三個不共線的點確定一個圓,圓上的一個點(原點)已經確定了,所以我們可以 O( n ) 枚舉一下另一個定點 P,此時大概是這個樣子
最后 O( n ) 枚舉點 A 時,此時不共線的三點已經可以確定一個圓了,換句話說,三個點就可以確定下來圓心的位置了,當點 P 和點 O 都確定下來后,枚舉點 A 所得到的所有圓心的眾數再加一,就是以此圓心做圓后可以經過的點的個數,利用map維護最大值就是答案了,找圓心的任務直接交給模板就好了
最后替出題人稍微解釋一下吧,并沒有卡 double 的精度,如果代碼只過了 90% 或 95% 的樣例的話,不妨看看下面兩個特判:
1
1?0
ans=1
3
1?0
2?0
3?0
ans=1?
代碼:
?
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=2e3+100;const double eps = 1e-6;int sgn(double x){if(fabs(x) < eps)return 0;if(x < 0)return -1;else return 1;
}struct Point{double x,y;Point(){}Point(double _x,double _y){x = _x;y = _y;}void input(){scanf("%lf%lf",&x,&y);}bool operator == (Point b)const{return sgn(x-b.x) == 0 && sgn(y-b.y) == 0;}bool operator < (Point b)const{return sgn(x-b.x)== 0?sgn(y-b.y)<0:x<b.x;}Point operator -(const Point &b)const{return Point(x-b.x,y-b.y);}//叉積double operator ^(const Point &b)const{return x*b.y - y*b.x;}//返回兩點的距離double distance(Point p){return hypot(x-p.x,y-p.y);}Point operator +(const Point &b)const{return Point(x+b.x,y+b.y);}Point operator /(const double &k)const{return Point(x/k,y/k);}//`逆時針旋轉90度`Point rotleft(){return Point(-y,x);}
}point[N];struct Line{Point s,e;Line(){}Line(Point _s,Point _e){s = _s;e = _e;}//`兩向量平行(對應直線平行或重合)`bool parallel(Line v){return sgn((e-s)^(v.e-v.s)) == 0;}//`求兩直線的交點`//`要保證兩直線不平行或重合`Point crosspoint(Line v){double a1 = (v.e-v.s)^(s-v.s);double a2 = (v.e-v.s)^(e-v.s);return Point((s.x*a2-e.x*a1)/(a2-a1),(s.y*a2-e.y*a1)/(a2-a1));}
};
//圓
struct circle{Point p;//圓心double r;//半徑circle(){}//`三角形的外接圓`//`需要Point的+ / rotate() 以及Line的crosspoint()`//`利用兩條邊的中垂線得到圓心`//`測試:UVA12304`circle(Point a,Point b,Point c){Line u = Line((a+b)/2,((a+b)/2)+((b-a).rotleft()));Line v = Line((b+c)/2,((b+c)/2)+((c-b).rotleft()));p = u.crosspoint(v);r = p.distance(a);}
};int main()
{
#ifndef ONLINE_JUDGE
// freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif
// ios::sync_with_stdio(false);int n;scanf("%d",&n);for(int i=1;i<=n;i++)point[i].input();if(n<=1)return 0*printf("%d\n",n);int ans=1;for(int i=1;i<=n;i++){map<Point,int>cnt;for(int j=i+1;j<=n;j++){if(Line(point[i],point[j]).parallel(Line(point[i],Point(0,0))))continue;circle c(point[i],point[j],Point(0,0));ans=max(ans,++cnt[c.p]+1);}}printf("%d\n",ans);return 0;
}
?
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生
總結
以上是生活随笔為你收集整理的牛客多校2 - Boundary(几何)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。