• 7.1.6 Maple trees



    Problem Description
    There are a lot of trees in HDU. Kiki want to surround all the trees with the minimal required length of the rope . As follow,

    To make this problem more simple, consider all the trees are circles in a plate. The diameter of all the trees are the same (the diameter of a tree is 1 unit). Kiki can calculate the minimal length of the rope , because it's so easy for this smart girl.
    But we don't have a rope to surround the trees. Instead, we only have some circle rings of different radius. Now I want to know the minimal required radius of the circle ring. And I don't want to ask her this problem, because she is busy preparing for the examination.
    As a smart ACMer, can you help me ?
     

    Input
    The input contains one or more data sets. At first line of each input data set is number of trees in this data set n (1 <= n <= 100), it is followed by n coordinates of the trees. Each coordinate is a pair of integers, and each integer is in [-1000, 1000], it means the position of a tree’s center. Each pair is separated by blank.
    Zero at line for number of trees terminates the input for your program.
     

    Output
    Minimal required radius of the circle ring I have to choose. The precision should be 10^-2.
     

    Sample Input
    2
    1 0
    -1 0
    0
     

    Sample Output
    1.50

    思路:最小圆覆盖

    有两种方法:一种是随机增量法,另一种是求凸包,再求三角形的最小覆盖圆,我用的是前者

    http://blog.sina.com.cn/s/blog_6e63f59e010120dl.html  (这篇文章讲的很好,尤其是对于怎么求三角形的外心)

    http://blog.csdn.net/lthyxy/article/details/6661250 (这篇是代码,但缺少一个很重要的就是对于三点共线的判断(虽然在随机情况下很少见))

    随机增量法简单的来说:假设我已经做出了一个圆,在1-n中选取第一个不在当前圆里的点,命名为i

    重复以上步骤,假设又以i为圆周上的点,选择了一个1至i-1里的点作为圆,又有一个点k,它不在这个圆内,分析当前这三点,很明显,k点跟i,j不可能构成钝角三角形(如果是钝角三角形),k已经包含在以i,j为直径的圆里了

    所以(当三点不共线时)求三角形外接圆,否则已知k点是最远点,取k与i,j距离最大为直径,算法结束,至于为什么是线性的,首先,一个点不在当前圆内的概率是3/i,

    有3/i的概率做到k,因为是三重循环,所以到i的期望复杂度是(3/i*3/i*i*i)=O(9),总共重复n此,期望9*O(n);

      1 #include <cmath>
      2 #include <cstdio>
      3 #include <algorithm>
      4 #include <cstring>
      5 #include <string>
      6 #include <cstdlib>
      7 using namespace std;
      8 
      9 typedef double dd;
     10 const int maxn=1210;
     11 const dd eps=1E-10;
     12 dd A1,B1,C1,A2,B2,C2,t;
     13 struct point
     14 {
     15     dd x,y,r;
     16 } p[maxn],o,h;
     17 dd x[20],y[20];
     18 int n;
     19 
     20 void close()
     21 {
     22 exit(0);
     23 }
     24 
     25 dd sqr(dd t)
     26 {
     27     return t*t;
     28 }
     29 
     30 int dblcmp(dd t)
     31 {
     32     if (fabs(t)<eps)
     33         return 0;
     34     if (t>0) return 1;
     35     return -1;
     36 }
     37 
     38 dd dist(point a,point b)
     39 {
     40     return sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) );
     41 }
     42 
     43 bool judge(int i)
     44 {
     45     if (dblcmp(dist(p[i],o)-o.r)==1)
     46         return false;
     47     return true;
     48 }
     49 
     50 dd mul(point a,point b,point c)
     51 {
     52     return ( (b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x) );
     53 }
     54 
     55 void update(int i,int j,int k)
     56 {
     57     if (dblcmp(mul(p[i],p[j],p[k]))==0)
     58     {
     59         if (dblcmp( dist(p[k],p[i])-dist(p[k],p[j]) ) >=0 )
     60             h=p[i];    else h=p[j];
     61         o.x=(h.x+p[k].x)/2.0;
     62         o.y=(h.y+p[k].y)/2.0;
     63         o.r=dist(o,p[k]);
     64         return;
     65     }
     66     x[1]=p[i].x; y[1]=p[i].y;
     67     x[2]=p[j].x; y[2]=p[j].y;
     68     A1 = (x[2]-x[1]);
     69     B1 = (y[2]-y[1]);
     70     C1=(sqr(x[2])-sqr(x[1]) + sqr(y[2])-sqr(y[1]))/2.0;
     71     ///////////////////////////////////////////////
     72     x[1]=p[i].x; y[1]=p[i].y;
     73     x[2]=p[k].x; y[2]=p[k].y;
     74     A2 = (x[2]-x[1]);
     75     B2 = (y[2]-y[1]);
     76     C2=(sqr(x[2])-sqr(x[1]) + sqr(y[2])-sqr(y[1]))/2.0;
     77     ///////////////////////////////////////////////
     78     t=A1*B2-A2*B1;
     79     o.x=(C1*B2-C2*B1)/t;
     80     o.y=(A1*C2-C1*A2)/t;
     81     o.r=dist(o,p[i]);    
     82 }
     83 
     84 void work()
     85 {
     86     o.r=0;
     87     o.x=p[1].x;
     88     o.y=p[1].y;
     89     for (int i=2;i<=n;i++)
     90     {
     91         if (judge(i)) continue;
     92         o=p[i];
     93         o.r=0;
     94         for (int j=1;j<=i-1;j++)
     95         {
     96             if (judge(j)) continue;
     97             o.x = (p[i].x + p[j].x) / 2;
     98             o.y = (p[i].y + p[j].y) / 2;
     99             o.r=dist(p[i],o);
    100             for (int k=1;k<=j-1;k++)//这里的循环很重要,一定是j-1,因为我是要保证做到i,j这个位置时,min(i,j)前面的k这三点构成最小圆,不能提前越界了
    101             {
    102                 if (judge(k)) continue;
    103                 update(i,j,k);
    104             }
    105         }
    106     }
    107 //    printf("x:%lf y:%lf
    ",o.x,o.y);
    108 }
    109 
    110 void init()
    111 {
    112     while(scanf("%d",&n)!=EOF)
    113     {
    114         if (n==0) break;
    115         for (int i=1;i<=n;i++)
    116             scanf("%lf %lf",&p[i].x,&p[i].y);
    117         work();
    118 //        printf("%.2lf %.2lf ",o.x,o.y);
    119         printf("%.2lf
    ",(o.r+0.5));
    120     }
    121 }
    122 
    123 int main ()
    124 {
    125     init();
    126     close();
    127     return 0;
    128 }
  • 相关阅读:
    VSS與CSV區別
    办公室中节约时间
    C#中用Smtp發郵件
    关于分层结构的感悟(轉)
    Visual Studio.Net 技巧(轉)
    常用數據庫訪問方式比較
    Winows部署中一些內容說明
    适配器模式(Adapter Pattern)(轉)
    Vistual Studio 2005 sp1補丁的詳細內容
    感情 程序 祭 【转】
  • 原文地址:https://www.cnblogs.com/cssystem/p/3188132.html
Copyright © 2020-2023  润新知