zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    泛微云桥e-Bridge 目录遍历,任意文件读取
    (CVE-2020-8209)XenMobile-控制台存在任意文件读取漏洞
    selenium 使用初
    将HTML文件转换为MD文件
    Python对word文档进行操作
    使用java安装jar包出错,提示不是有效的JDK java主目录
    Windows server 2012安装VM tools异常解决办法
    ifconfig 命令,改变主机名,改DNS hosts、关闭selinux firewalld netfilter 、防火墙iptables规则
    iostat iotop 查看硬盘的读写、 free 查看内存的命令 、netstat 命令查看网络、tcpdump 命令
    使用w uptime vmstat top sar nload 等命令查看系统负载
  • 原文地址:https://www.cnblogs.com/cssystem/p/3188132.html
Copyright © 2011-2022 走看看