Codeforces Round #311 (Div. 2) Problem B

    2015年7月2日

    題目描述:輸入兩個整數n(1 <= n <= 10^5),w(1 <= w <= 10^9)。n表示有n個男孩和n個女孩,共2n個人;w表示有一個容器的盛有w毫升的水,然後第二行輸入2n整數arr[i](1 <= arr[i] <= 10^9),表示有2n個容器,第i個容器的容量是arr[i],讓後用着w毫升水在這2 * n個容器裏倒水,有兩個條件:倒出的水總容量小於等於w,每個男孩的杯子的盛水是n任意女孩的兩倍,求能倒出水最大容量是多少。

    
    例如:
    input
    1 5
    2 3
    output
    4.5
    樣例解釋:有1個男孩,1個女孩,一個杯子的容量是2,一個杯子的容量是3,在容量大小爲2的杯子倒入1.5毫升的水,這個杯子被女孩佔用,另一個杯子的容量是3,倒入3毫升的水,總倒出的水是4.5毫升小於等於5毫升,並且女孩的水容量是男孩的一半。


    題目很明確地說,每一個女生所盛的水是任意一個男生的一半,通過這個條件能夠得到一個結論:每個女生所盛的水是相同的,男生也是相同的,並且女生的所盛水的容量是男生的一半。
    給了2n個杯子盛水。將這2n個杯子按容量的大小排序將arr[0]作爲女孩的基礎杯子容量,arr[n]作爲男孩的基礎杯子,將問題的規模抽象出來就是:
    在[0,min(arr[0], arr[n] / 2)]中尋找一個值x,這個x是一個女孩的最終的容量,所以一個男孩的容量就是2x,這個x是屬於[0, arr[0]], 2x 屬於[0, arr[n]],並且要讓這個x儘量大,此時會想到的一個算法就是二分查找去搜索這個x。
    應爲數據x有可能會是浮點數,所以比較的時候就會出現浮點數跟整數比較,直接用“==”比較是不合理的,是有精度遺失的,這裏的處理是用一個EPS來處理精度問題,a <= b可以等價轉化爲(b - a)>= EPS。這個EPS的精度要去多大是一個很不明確的值,有時取得過大是會出現精度損失,過小會比較耗時(即有可能會超時),據測試這裏取1e-11,1e-12是合理的。

#include <bits/stdc++.h>
#define MAXN 200007
#define EPS 1e-11 //精度問題一定要取合理,太小有誤差,太大會超時
using namespace std;
double arr[MAXN];
int main()
{
    int n;
    double w;
    cin >> n >> w;
    for(int i = 0; i < 2 * n; ++i)
        scanf("%lf", &arr[i]);
    sort(arr, arr + 2 * n);
    double L = 0, R = min(arr[0], arr[n] / 2); 
    //在[0, min(arr[0], arr[n] / 2)]中二分搜索答案
    while(fabs(R - L) > EPS) 
    {//當R - L大於EPS時就繼續找更優的值
        double M = L + (R - L) / 2;
        if((arr[n] - M * 2) >= EPS && (w - M * 3 * n) >= EPS) L = M;
        //如果M是滿足條件的值,則試圖向右邊區間找更合理的答案
        else R = M;
        //否則在左邊的區間找更合理的答案
    }
    printf("%lf\n", L * 3 * n);
    return 0;
}


    轉載請註明出處:http://blog.csdn.net/royecode
發佈了24 篇原創文章 · 獲贊 6 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章