三分

在這裏插入圖片描述
根據題目,在一個二維座標中,我們要輸入N個點座標,而在x軸(-10000,10000)這個區間存在無數個點,我們假設它爲x1,x2,x3…這些點中,每個點到我們輸入的N個點的距離存在一個最大值,我們要在這些最大值中找到最小的那一個然後輸出。
那麼,思路是什麼呢?
既然存在這樣一個點,那麼我們就要找到它所在的那個區間。但是,這裏要注意了,是最小值,有最值,而且是最小值,那麼就可以用三分法,那爲什麼不用二分法呢?因爲二分法是對與單調區間的,(這在高中大家接觸二分法的時候舉得例子就是單調函數吧,我記得好像是單調且端點異號。)而三分法是針對有峯值的函數的。顯然,在本題中,用三分法是更加方便快捷的。其實,二分法也可以用,就是對分下來的每一個區間進行再次二分。我覺得要用到遞歸好像。二分法比較複雜一點。後面我掌握後一定會及時向大家分享的。
下面,我們就來介紹一下三分法的解題步驟:
1.首先,我們要將先分爲兩半,然後在對其中的一變進行再分兩半,總體就是2:1:1的形式。這裏,我們用mid表示一半,用midmid表示一半的一半。

double check(double x){
    double max=0;
    for(int i=0;i<n;i++){
        double temp=sqrt(a[i].y*a[i].y+(a[i].x-x)*(a[i].x-x));
        if(temp>max)  max=temp;
    }
    return max;
}

我們就是將在x軸座標的某個點,到所有的N個點的最大值求出並且返回。

double thsearch(double l,double r)
{
    double mid,midmid;
    for(int i=0;i<100;i++){
        mid=l+(r-l)/2;
        midmid=mid+(r-mid)/2;
        if(check(mid)>check(midmid))l=mid;
        else r=midmid;
    }
    return mid;
}

我們先搞清楚這個循環,對於這個循環有人可能會問了?爲什麼是100,其他可不可以,答案是:可以,我們先講講這個原理,每一次循環,都將剩餘的區間進行了又一次的三分,這都是2的負次冪級的下降。所以,大家可以想想,2的-100次冪再乘以區間長度的值應該是足夠精確的了。其實也可以50,30等。但博主試了一下,好像3也是可以過的,emmm,這就要看測試數據本身了,我們爲了保險起見,還是將值設大一點。
然後,對於循環語句塊,首先,mid我們代表的是區間中點,而midmid有代表的是區間中點的中點。那這裏可能又有人要問了,爲什麼將midmid放在中點左邊呢?其實,你要想,也可以放在中點的右邊,只是將代碼進行一些細微的修改罷了,更有甚者,還可以兩邊都來個for循環,emmm,只是,沒有必要!

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const double pi=acos(-1),eps=1e-10;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
int n;
struct node{
    int x,y;
}lg[100010];

bool cmp(node a,node b)
{
    return a.x<b.x;
}
double check(double x)
{
    double maxx=0;
    for(int i=0;i<n;i++){
        double tmp=sqrt((lg[i].x-x)*(lg[i].x-x)+lg[i].y*lg[i].y);
        //cout<<tmp<<endl;
        if(tmp>maxx)maxx=tmp;
    }
    return maxx;
}
double thsearch(double l,double r)
{
    double mid,midmid;
    for(int i=0;i<100;i++){
        mid=l+(r-l)/2;
        midmid=mid+(r-mid)/2;
        if(check(mid)>check(midmid))l=mid;
        else r=midmid;
    }
    return mid;
}

int main()
{
    cin>>n;
    for(int i=0;i<n;i++)cin>>lg[i].x>>lg[i].y;
    //sort(lg,lg+n,cmp);
    //double l=lg[0].x,r=lg[n-1].x;
    double max=thsearch(-10000,10000);
    printf("%.4f\n",check(max));

    return 0;
}

發佈了16 篇原創文章 · 獲贊 29 · 訪問量 994
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章