標籤:its 一個 bsp 哈爾濱 main names bit class can
題面
題意:給你n個點,讓你找到一個圓,輸出圓心,和半徑,使得有超過一半的點剛好在圓上.n<=1e5,題目保證了有解
題解:剛開始看著很不可做的樣子,但是多想想,三點確定一個圓,三點啊!
現在有1/2的點都在圓上,意味著很多選出來的3個點都會導致同樣的結果啊
我們同時可以說,每次隨機一個點,這個點在圓上的機率為1/2,那任意三個點同時在圓上的機率就是1/8
所以我們隨機來個幾萬次就好了啊!
注意的就是點數<=4的時候,1的時候輸出自己就可以了,2,3,4的時候隨便輸出2個點的中點就行了
1 #include<bits/stdc++.h> 2 using namespace std; 3 struct point 4 { 5 double x,y; 6 }a[100005],pp; 7 int T,n,x,y,z; 8 #define eps 1e-10 9 double R;10 point cit(point a,point b,point c)11 {12 point cp;13 double a1=b.x-a.x,b1=b.y-a.y,c1=(a1*a1+b1*b1)/2;14 double a2=c.x-a.x,b2=c.y-a.y,c2=(a2*a2+b2*b2)/2;15 double d=a1*b2-a2*b1;16 cp.x=a.x+(c1*b2-c2*b1)/d;17 cp.y=a.y+(a1*c2-a2*c1)/d;18 return cp;19 }20 double dis(point a,point b)21 {22 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));23 }24 int ok(point p)25 {26 int tot=0;27 for (int i=1;i<=n;i++)28 {29 if (fabs(dis(p,a[i])-R)<eps) tot++;30 if (tot>=(n+1)/2) return 1;31 }32 return 0;33 }34 int kk(point x,point y,point z)35 {36 if ((x.x-y.x)*(x.y-z.y)==(x.y-y.y)*(x.x-z.x)) return 1;37 return 0;38 }39 int main()40 {41 srand(time(0));42 scanf("%d",&T);43 while (T--)44 {45 scanf("%d",&n);46 for (int i=1;i<=n;i++) scanf("%lf%lf",&a[i].x,&a[i].y);47 if (n==1)48 {49 printf("%lf %lf 0\n",a[1].x,a[1].y);50 continue;51 } 52 if (n<=4)53 {54 pp.x=(a[1].x+a[2].x)/2;55 pp.y=(a[1].y+a[2].y)/2;56 printf("%lf %lf %lf\n",pp.x,pp.y,dis(pp,a[1]));57 continue;58 }59 for (int i=1;i<=5000000;i++)60 {61 x=rand()*rand()%n+1;62 y=rand()*rand()%n+1;63 z=rand()*rand()%n+1;64 if (x==y || y==z || x==z) continue;65 if (kk(a[x],a[y],a[z])) continue;66 pp=cit(a[x],a[y],a[z]);67 R=dis(pp,a[x]);68 if (ok(pp))69 {70 printf("%lf %lf %lf\n",pp.x,pp.y,R);71 break;72 }73 }74 }75 }
2017CCPC-哈爾濱站 Hdu-6242 Geometry Problem 計算幾何 隨機