zoukankan      html  css  js  c++  java
  • hdu3007Buried memory(最小圆覆盖)

    链接

    普通的暴力复杂度达到O(n^4),对于这题肯定是不行的。

    解法:随机增量算法

    参考http://www.2cto.com/kf/201208/149602.html

    algorithm:
    A、令Ci表示为前i个点的最小覆盖圆。当加入新点pi时如果pi不在Ci-1里那么pi必定在Ci的边界上。
    B、再从新考虑这样一个问题,Ci为前i个点最小覆盖圆且p在Ci的的边界上!同理加入新点pi时如果p
    i不在Ci-1里那么pi必定在Ci的边界上。这时我们就包含了两个点在这个最小圆的边界上。
    C、再从新考虑这样一个问题,Ci为前i个点最小覆盖圆且有两个确定点再边界上!此时先让
    O(N)的方法能够判定出最小圆。
    ------------------------------------------------------------------------------------
    analysis:
    现在来分析为什么是线性的。
    C是线性的这是显然的。
    B<-C的过程中。考虑pi 他在园内的概率为 (i-1)/i 。在圆外的概率为 1/i 所以加入pi的期望复杂度为:(1-i)/i*O(1) +(1/i)*O(i) {前者在园内那么不进入C,只用了O(1)。后者进入C用了O(i)的时间}这样分析出来,复杂度实际上仍旧
    是线性的。
    A<-B的过程中。考虑方法相同,这样A<-B仍旧是线性。于是难以置信的最小圆覆盖的复杂度变成了线性的。

     1 #include <iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<stdlib.h>
     6 #include<vector>
     7 #include<cmath>
     8 #include<queue>
     9 #include<set>
    10 using namespace std;
    11 #define N 505
    12 #define LL long long
    13 #define INF 0xfffffff
    14 const double eps = 1e-8;
    15 const double pi = acos(-1.0);
    16 const double inf = ~0u>>2;
    17 struct point
    18 {
    19     double x,y;
    20     point(double x=0,double y = 0):x(x),y(y){}
    21 }p[N];
    22 typedef point pointt ;
    23 pointt operator -(point a,point b)
    24 {
    25     return point(a.x-b.x,a.y-b.y);
    26 }
    27 int dcmp(double x)
    28 {
    29     if(fabs(x)<eps) return 0;
    30     return x<0?-1:1;
    31 }
    32 double dis(point a)
    33 {
    34     return sqrt(a.x*a.x+a.y*a.y);
    35 }
    36 point circumcenter(point a, point b, point c)
    37 { //返回三角形的外心
    38     point ret;
    39     double a1 = b.x-a.x,b1 = b.y-a.y,c1 = (a1*a1+b1*b1)/2;
    40     double a2 = c.x-a.x,b2 = c.y-a.y,c2 = (a2*a2+b2*b2)/2;
    41     double d = a1*b2-a2*b1;
    42     ret.x=a.x+(c1*b2-c2*b1)/d;
    43     ret.y=a.y+(a1*c2-a2*c1)/d;
    44     return ret;
    45 }
    46 void min_cover_circle(point p[],int n,point &c,double &r)
    47 {
    48     random_shuffle(p,p+n);
    49     c = p[0],r = 0;
    50     int i,j,g;
    51     for(i = 1; i < n ;i++)
    52     {
    53         if(dcmp(dis(p[i]-c)-r)>0)
    54         {
    55             c = p[i];
    56             r = 0;
    57             for(j = 0; j < i ; j++)
    58             {
    59                 if(dcmp(dis(p[j]-c)-r)>0)
    60                 {
    61                     c = point((p[i].x+p[j].x)/2,(p[i].y+p[j].y)/2);
    62                     r = dis(p[j]-c);
    63                     for(g = 0 ; g < j; g++)
    64                     if(dcmp(dis(p[g]-c)-r)>0)
    65                     {
    66                         c = circumcenter(p[i],p[j],p[g]);
    67                         r = dis(p[i]-c);
    68                     }
    69                 }
    70             }
    71         }
    72     }
    73 }
    74 int main()
    75 {
    76     int n,i;
    77     while(scanf("%d",&n)&&n)
    78     {
    79         for(i = 0; i < n; i++)
    80         scanf("%lf%lf",&p[i].x,&p[i].y);
    81         point c;
    82         double r;
    83         min_cover_circle(p,n,c,r);
    84         printf("%.2f %.2f %.2f
    ",c.x,c.y,r);
    85     }
    86     return 0;
    87 }
    View Code
     1 #include <iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<stdlib.h>
     6 #include<vector>
     7 #include<cmath>
     8 #include<queue>
     9 #include<set>
    10 using namespace std;
    11 #define N 505
    12 #define LL long long
    13 #define INF 0xfffffff
    14 const double eps = 1e-8;
    15 const double pi = acos(-1.0);
    16 const double inf = ~0u>>2;
    17 struct point
    18 {
    19     double x,y;
    20     point(double x=0,double y = 0):x(x),y(y){}
    21 }p[N];
    22 typedef point pointt ;
    23 pointt operator -(point a,point b)
    24 {
    25     return point(a.x-b.x,a.y-b.y);
    26 }
    27 int dcmp(double x)
    28 {
    29     if(fabs(x)<eps) return 0;
    30     return x<0?-1:1;
    31 }
    32 double dis(point a)
    33 {
    34     return sqrt(a.x*a.x+a.y*a.y);
    35 }
    36 point circumcenter(point a, point b, point c)
    37 { //返回三角形的外心
    38     point ret;
    39     double a1 = b.x-a.x,b1 = b.y-a.y,c1 = (a1*a1+b1*b1)/2;
    40     double a2 = c.x-a.x,b2 = c.y-a.y,c2 = (a2*a2+b2*b2)/2;
    41     double d = a1*b2-a2*b1;
    42     ret.x=a.x+(c1*b2-c2*b1)/d;
    43     ret.y=a.y+(a1*c2-a2*c1)/d;
    44     return ret;
    45 }
    46 void min_cover_circle(point p[],int n,point &c,double &r)
    47 {
    48     random_shuffle(p,p+n);
    49     c = p[0],r = 0;
    50     int i,j,g;
    51     for(i = 1; i < n ;i++)
    52     {
    53         if(dcmp(dis(p[i]-c)-r)>0)
    54         {
    55             c = p[i];
    56             r = 0;
    57             for(j = 0; j < i ; j++)
    58             {
    59                 if(dcmp(dis(p[j]-c)-r)>0)
    60                 {
    61                     c = point((p[i].x+p[j].x)/2,(p[i].y+p[j].y)/2);
    62                     r = dis(p[j]-c);
    63                     for(g = 0 ; g < j; g++)
    64                     if(dcmp(dis(p[g]-c)-r)>0)
    65                     {
    66                         c = circumcenter(p[i],p[j],p[g]);
    67                         r = dis(p[i]-c);
    68                     }
    69                 }
    70             }
    71         }
    72     }
    73 }
    74 int main()
    75 {
    76     int n,i;
    77     while(scanf("%d",&n)&&n)
    78     {
    79         for(i = 0; i < n; i++)
    80         scanf("%lf%lf",&p[i].x,&p[i].y);
    81         point c;
    82         double r;
    83         min_cover_circle(p,n,c,r);
    84         printf("%.2f %.2f %.2f
    ",c.x,c.y,r);
    85     }
    86     return 0;
    87 }
    View Code
  • 相关阅读:
    nth-of-type()的用法
    H5禁止底部横向滚动条,使一个元素居中
    CRM项目-1模型与站点管理
    django-debug-toolbar
    python发送邮件
    os 模块
    Django(三) ORM操作
    Django框架初识
    JS 正则表达式
    前端-高潮 jQuery
  • 原文地址:https://www.cnblogs.com/shangyu/p/3891061.html
Copyright © 2011-2022 走看看