zoukankan      html  css  js  c++  java
  • 最小圆覆盖模板

    //最小圆覆盖
    //输入: 从下标0开始的点集_ps和大小_n
    //输出: 覆盖所有点的最小圆
    //复杂度: O(n)
    //注意: 会对_ps进行随机处理操作,将会改变点集的内部顺序
    Circle MinCoverCir(Point _ps[],int _n)
    {
        //随机处理,但是会改变传入的点集。
        random_shuffle(_ps, _ps+_n);//复杂度O(_n)
        
        Circle rec;
        rec.r = 0;
        rec.c = _ps[0];
        for(int i=1;i<_n;i++)
        {
            if(GT( Dis(rec.c,_ps[i]),rec.r ) )//i点在圆外
            {
                rec.r = 0;
                rec.c = _ps[i];
                for(int j=0;j<i;j++)
                {
                    if( GT( Dis(rec.c,_ps[j]),rec.r ) )//j在圆外
                    {
                        rec.c.x = (_ps[i].x+_ps[j].x)/2.0;
                        rec.c.y = (_ps[i].y+_ps[j].y)/2.0;
                        rec.r = Dis(_ps[i],_ps[j])/2.0;
                        for(int k=0;k<j;k++)
                        {
                            if( GT( Dis(rec.c,_ps[k]),rec.r ) )//k在圆外
                            {
                                rec=OutCircle(_ps[i], _ps[j], _ps[k]);
                            }
                        }
                    }
                }
            }
        }
        return rec;
    }

    为什么这样做,我觉得看代码比看解释清晰的多。 最关键需要证明的一步在于,为什么在确定i,j必在圆上后,当出现一个不在圆内的点k时,用i,j,k的外接圆代替。这个画几个图用点几何知识即可证明。然后理论复杂度是O(n)的,看起来虽然是n^3,但是每一层往下的可能都是log的,所以平均起来最多是O(n+(logn)^3) = O(n)。这个算法真是尼玛巧妙。

  • 相关阅读:
    MyEclipse编码集设置
    Tomcat内存溢出问题解决
    避免头文件多次编译
    C++指针学习(1)
    C++头文件和实现(用复数类举例)
    从helloworld开始
    标准库string类型
    浅谈Lua的Coroutine协程的多"线程"并发模型
    关于闭包函数的概念和原理
    笔记
  • 原文地址:https://www.cnblogs.com/chenhuan001/p/5117703.html
Copyright © 2011-2022 走看看