最小覆蓋圓的神奇算法及例題


最近翔哥上課講計算幾何這個神奇玩意。然后一堆新高一創新班的都特High,然后我們一堆初二的ZZ全程懵逼。

但是剛開始講的這個東西還是令人耳目一新的。

何為最小覆蓋圓,顧名思義,就是覆蓋平面內所有點的最小的圓。

原來隨機化算法這么強勁?好了我們來看這個算法——隨機增量法

一看名字就知道,先要把輸入的點打亂,使其隨機化。玄學

然后就是從第一個點開始枚舉點\(i\),如果當前的枚舉的點在圓內部,就繼續不用管(顯然的)。否則就以該點為圓心半徑為\(0\)開始枚舉\(j(1\le j < i)\)

如果\(j\)在當前圓的外面就取點\(i\)和點\(j\)的中點為圓心,距離的一半為半徑(兩點的最小覆蓋圓)。以這個圓再枚舉\(k(1\le k<j)\),然后如果點\(k\)在圓外(這和上面的都是一樣的)。就以\(i,j,k\)三點在計算最小覆蓋圓。

而這個最小覆蓋圓就是前\(i\)個點的最小覆蓋圓。

然后最大的問題就在於這個已知三點求圓的圓心及半徑的過程了。這里給出弱弱的解析幾何方法計算幾何我不會啊

我們要先知道一個關於圓的公式:

\(x^2+y^2=r^2\)

然后我們設圓心的坐標為\((x_0,y_0)\)然后就可以列一個三元二次方程解出\(x_0,y_0\)的值。

但是具體的解法太過技術性,找到一篇超級詳細的解法。請仔細參閱。

然后就是堅定不移的相信自己是歐皇然后不被卡精度

但是這個復雜度就是玄學\(O(n)\)(具體證明參考dalao‘s blog

板子(就是那個min_cover_circleEnglish level is too low)

inline DB power(DB x)
{
    return x*x;
}
inline DB dis(node a,node b)
{
    return sqrt(power(a.x-b.x)+power(a.y-b.y));
}
inline bool in_circle(node a)

    return dis(a,O)<=r?1:0;
}
inline void calc(DB a,DB b,DB c,DB d,DB e,DB f)
{
    O.x=(b*f-d*e)/(b*c-a*d);
    O.y=(c*e-a*f)/(b*c-a*d);
}
inline void min_cover_circle(void)
{
    register int i,j,k;
    random_shuffle(a+1,a+n+1);
    for (i=1;i<=n;++i)
    if (!in_circle(a[i]))
    {
        O=a[i]; r=0;
        for (j=1;j<i;++j)
        if (!in_circle(a[j]))
        {
            O.x=(a[i].x+a[j].x)/2.0; O.y=(a[i].y+a[j].y)/2.0; r=dis(a[i],O);
            for (k=1;k<j;++k)
            if (!in_circle(a[k])) calc(a[i].x-a[j].x,a[i].y-a[j].y,a[i].x-a[k].x,a[i].y-a[k].y,
            ((power(a[i].x)-power(a[j].x))-(power(a[j].y)-power(a[i].y)))/2.0,
            ((power(a[i].x)-power(a[k].x))-(power(a[k].y)-power(a[i].y)))/2.0),r=dis(a[i],O);
        }
    }
}

最后求出的O就是原點,r是半徑。

然后我們來看一些板子題:

HDU3007

這題的數據范圍很小。盡管我們\(O(n^3)\)大暴力是可以過的,但是對於新的算法還是要練習一下。

BZOJ1336&&BZOJ1337&&BZOJ2823

BZOJ的數據強度比較高,但那個神奇精度問題實在是。。。。。。

樣例保留兩位,實際上要保留10位,題目也沒講。這是讓我們猜數據范圍么?

Luogu P1742 最小圓覆蓋&&Luogu P2533 [AHOI2012]信號塔

和BZOJ的基本就是重題,但是多虧洛谷才搞懂了數據范圍。

莫名弄了一個玄學省選算法。還是挺棒的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM