• P2533 [AHOI2012]信号塔 P1742 最小圆覆盖


    只会随机增量法

    正确性:
    显然,这个圆一定是某两个点的外接圆或者某个三角形的外接圆 ,否则就可以变得更小了

    时间复杂度 期望是(O(n))
    我们先随机生成i个点,求出他们的最小覆盖圆,我们可以认为这个圆是由现在在边界上的那三个点来确定的,也就是说当随机生成的最后一个点不是那三个点时,新生成的点就在圆内,否则在圆外,所以第i个点在前i-1个点的最小覆盖圆外的概率只有3/i
    三个点,那么期望就是O(n)咯,但是如果是特殊构造的数据可能卡到(O(n^3))

    贴下求三角形外接圆圆心坐标的公式

    [left{egin{array}{l} left(x_{1}-x_{0} ight)^{2}+left(y_{1}-y_{0} ight)^{2}=r^{2} (1)\ left(x_{2}-x_{0} ight)^{2}+left(y_{2}-y_{0} ight)^{2}=r^{2} (2)\ left(x_{3}-x_{0} ight)^{2}+left(y_{3}-y_{0} ight)^{2}=r^{2} (3) end{array} ight. ]

    1,2相减,1,3相减可以得到

    [ egin{array}{l} left(x_{1}-x_{2} ight) x_{0}+left(y_{1}-y_{2} ight) y_{0}=frac{left(x_{1}^{2}-x_{2}^{2} ight)-left(y_{2}^{2}-y_{1}^{2} ight)}{2} \ left(x_{1}-x_{3} ight) x_{0}+left(y_{1}-y_{3} ight) y_{0}=frac{left(x_{1}^{2}-x_{3}^{2} ight)-left(y_{3}^{2}-y_{1}^{2} ight)}{2} end{array} ]

    [egin{array}{l} a=x_{1}-x_{2} \ b=y_{1}-y_{2} \ c=x_{1}-x_{3} \ d=y_{1}-y_{3} \ e=frac{left(x_{1}^{2}-x_{2}^{2} ight)-left(y_{2}^{2}-y_{1}^{2} ight)}{2} \ f=frac{left(x_{1}^{2}-x_{3}^{2} ight)-left(y_{3}^{2}-y_{1}^{2} ight)}{2} end{array} ]

    [egin{array}{l} x_{0}=frac{d e-b f}{b c-a d} \ y_{0}=frac{a f-c e}{b c-a d} end{array} ]

    #include<bits/stdc++.h>
    #define rep(i,j,k) for(int i(j);i<=k;++i)
    #define drp(i,j,k) for(int i(j);i>=k;--i)
    #define repg(x) for(int i(G.head[x]);i;i=G.next[i])
    #define bug cout<<"~~~~~~~~~~~~~"<<'
    ';
    using std::cin;
    using std::cout;
    typedef long long lxl;
    template<typename T>
    inline T  max( T a, T b) {
    	return a > b ? a : b;
    }
    template<typename T>
    inline T  min( T a, T b) {
    	return a < b ? a : b;
    }
    std::mt19937 r(std::chrono::system_clock::now().time_since_epoch().count());
    const int N = 1e6 + 79;
    struct point {
    	double x, y;
    	point() {
    		x = y = 0.0;
    	}
    
    } t[N], O; //Ô²ÐÄ
    
    inline double dis(const point &rr,const point &r) {
    	return sqrt( (rr.x - r.x) * (rr.x - r.x) + (rr.y - r.y) * (rr.y - r.y));
    }
    
    
    const double eps = 1e-6;
    double R;
    inline bool incircle(const point &x) {
    	return dis(x, O) - R < eps;
    }
    
    inline point calc(point p1,point p2,point p3){
        double a,b,c,d,e,f;
        
        a=p2.y-p1.y;
        b=p3.y-p1.y;
        c=p2.x-p1.x;
        d=p3.x-p1.x;
        f=p3.x*p3.x+p3.y*p3.y-p1.x*p1.x-p1.y*p1.y;
        e=p2.x*p2.x+p2.y*p2.y-p1.x*p1.x-p1.y*p1.y;
        
        point ans;
        ans.x=(a*f-b*e)/(2*a*d-2*b*c);
        ans.y=(d*e-c*f)/(2*a*d-2*b*c);
        R=dis(p1,ans);
        return ans;
    }
    
    
    
    
    int n;
    int main() {
    	std::ios::sync_with_stdio(false);
    
    	cin >> n;
    	rep(i, 1, n) {
    		cin >> t[i].x >> t[i].y;
    	}
    
    	srand(r());
    	std::random_shuffle(t + 1, t + n + 1);
    
    	O = t[1];
    	rep(i, 1, n) {
    		if(incircle(t[i])) continue;
    		O = t[i];
    		rep(j, 1, i - 1) {
    			if(incircle(t[j]))	 continue;
    			O.x = (t[i].x + t[j].x) / 2.0;
    			O.y = (t[i].y + t[j].y) / 2.0;
    			R = dis(t[i], t[j]) / 2.0;
    
    			rep(k, 1, j - 1) {
    				if(incircle(t[k])) continue;
    				{
    					O = calc(t[i], t[j], t[k]);
    					R = dis(O, t[i]);
    				}
    
    			}
    		}
    	}
    	cout << std::fixed << std::setprecision(10) << R << '
    '<< O.x << ' ' << O.y << ' ' ;
    	return 0;
    }
    

    本文来自博客园,作者:{2519},转载请注明原文链接:https://www.cnblogs.com/QQ2519/p/15465030.html

  • 相关阅读:
    js-YDUI 移动端解决方案
    js 关于网易淘宝移动端适配的学习
    JavaScript--数据结构与算法之排序
    《致橡树》
    JavaScript--Module模式
    js-轮播图的总结
    flex布局:
    JavaScript--模块化 JavaScript module designer
    JavaScript--数据结构之队列
    剑指offer——数组中的逆序对
  • 原文地址:https://www.cnblogs.com/QQ2519/p/15465030.html
Copyright © 2020-2023  润新知