2017CCPC-哈尔滨站 Hdu-6242 Geometry Problem 计算几何 随机

题面

题意:给你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 }

原文地址:https://www.cnblogs.com/qywhy/p/9748389.html

时间: 2024-10-11 04:57:55

2017CCPC-哈尔滨站 Hdu-6242 Geometry Problem 计算几何 随机的相关文章

2017 CCPC 哈尔滨站 HDU 6242

Geometry Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 1091    Accepted Submission(s): 208Special Judge Problem Description Alice is interesting in computation geometry problem recen

HDU 6242 Geometry Problem(计算几何 + 随机化)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6242 思路:当 n == 1 时 任取一点 p 作为圆心即可. n >= 2 && n < 5 时 此时有可能出现所有点共线,所以取任意俩点间中点作为圆的圆心. n >= 5 保证了有解.所以不可能有所有点共线的情况,随机取三个点在正解圆上的概率是 1/8,还是蛮大的.... 外学了下随机算法的写法....时间种子 time(0)要强制转成int,不然会WA,不造为啥....

HDU - 6242:Geometry Problem(随机+几何)

Alice is interesting in computation geometry problem recently. She found a interesting problem and solved it easily. Now she will give this problem to you : You are given NN distinct points (Xi,Yi)(Xi,Yi) on the two-dimensional plane. Your task is to

hdoj 1086 You can Solve a Geometry Problem too 【计算几何】

题意:就是判断各线段之间有没有交点. 判断两线段相交,要运用到叉积.两个线段相交肯定相互跨越,假设一个条线段(p1p2),另一条是(q1q2),那么p1p2肯定在q1q2线段的两侧,那么运用叉积如果p1p2跨越q1q2的话(q1p1)x(q2p2)<= 0.同样也要验证 q1q2是不是也跨越p1p2,注意:p1p2跨越q1q2,不代两个线段相交,可能是p1p2跨越直线q1q2,所以说还是要再次判断q1q2是不是跨越p1p2 还有另外一种比较容易理解的解法: 就是如果两个线段相交,那么两线段两端端

HDU 1086 You can Solve a Geometry Problem too(判断线段相交)

题目地址:HDU 1086 就这么一道仅仅判断线段相交的题目写了2k多B的代码..是不是有点浪费...但是我觉得似乎哪里也优化不了了.... 判断线段相交就是利用的叉积.假如现在两条线段分别是L1和L2,先求L1和L2两个端点与L1的某个端点的向量的叉积,如果这两个的叉积的乘积小于0的话,说明L1在是在L2两个端点之间的,但此时并不保证一定相交.此时需要用同样的方法去判断L2是否在L1的两个端点之间,如果L2也在L1的两个端点之间的话,那就足以说明L1与L2相交.但是这题还需要判断是否端点也相交

HDU 1086:You can Solve a Geometry Problem too

You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6997    Accepted Submission(s): 3385 Problem Description Many geometry(几何)problems were designed in the ACM/

hdu 1086 You can Solve a Geometry Problem too (几何)

You can Solve a Geometry Problem too Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6932    Accepted Submission(s): 3350 Problem Description Many geometry(几何)problems were designed in the ACM/I

hdu 1086 You can Solve a Geometry Problem too(求线段相交点个数 模板)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1086 ---------------------------------------------------------------------------------------------------------------------------------------------------------- 欢迎光临天资小屋:http://user.qzone.qq.com/593830943

HDU1086 You can Solve a Geometry Problem too(计算几何)

You can Solve a Geometry Problem too                                         Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)                                         Problem Description Many geometry(几何)problems wer