二分查找 Problem 1003 Pie

Problem ID:1003  Pie


簡單題意:有N塊pie,分給F+1個人。每塊pie的高度都是1,但半徑不一定相同。每個人都要分到相同體積的pie,但是每個人只能得到一塊pie,不能是好幾塊拼湊起來。可以浪費掉一部分。給出N、F、每塊pie的半徑ri,求出每個人將會得到的pie的最大體積V。


解題思路形成過程:一個人最多可以分到最大的那塊pie的體積,最少可以分到0,利用二分法,求出滿足要求的每個人將會得到的pie的最大體積V。


感想:一開始沒有考慮到會是二分法,用的另一種方法,WA了好多次,怎麼改也不行,二分法AC了以後,仔細想了想才發現一開始的算法有嚴重的漏洞。

在開始寫代碼前,要仔細思考、確定自己的算法到底正不正確,有沒有漏洞,有沒有一些情況尤其是一些特殊、邊界情況沒有考慮到。當確定自己的算法無誤後再開始寫代碼。


代碼:

#include<iostream>
#include<stdio.h>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;
#define pi acos(-1.0)           //acos:反餘弦。 cosπ=-1,所以-1的反餘弦就是π。 這樣能夠提高精確率。
bool cmp(double a,double b)
{
    return a>b;
}
int main()
{
    int n;
    //freopen("1.txt","r",stdin);
    cin>>n;
    while(n--)
    {
        int N,F;
        cin>>N>>F;
        ++F;
        vector <double> ri;
        for(int i=0;i<N;++i){
            int temp1;
            scanf("%d",&temp1);
            double temp2=pi*pow(temp1,2);
            ri.push_back(temp2);//直接存入每個pie的體積。
        }
        sort(ri.begin(),ri.end(),cmp);
        double l=0,r=ri[0];     //ri[0]爲最大的pie的體積。
        double mid=(l+r)/2;
        while(r-l>1e-7){        //注意題目中要求的最低精確度。
            int total=0;
            for(int i=0;i<N;++i)
                total+=(int)(ri[i]/mid);//一定注意強制轉換及其正確用法!!很容易出錯!
            if(total>=F)
                l=mid;
            else
                r=mid;
            mid=(l+r)/2;
        }
        printf("%.4lf\n",mid);
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章