【UVA12097】Pie

題面

  My birthday is coming up and traditionally I’m serving pie. Not just one pie, no, I have a number N of them, of various tastes and of various sizes. F of my friends are coming to my party and each of them gets a piece of pie. This should be one piece of one pie, not several small pieces since that looks messy. This piece can be one whole pie though.
  My friends are very annoying and if one of them gets a bigger piece than the others, they start com-plaining. Therefore all of them should get equally sized (but not necessarily equally shaped) pieces,even if this leads to some pie getting spoiled (which is better than spoiling the party). Of course, I want a piece of pie for myself too, and that piece should also be of the same size.
  What is the largest possible piece size all of us can get? All the pies are cylindrical in shape and they all have the same height 1, but the radii of the pies can be different.

題意

  有n 個餅,半徑爲riri104 ),分給f+1 個人,要求每個人分到的面積是一樣的,而且每個人分到的餅是連續的一塊(即不能是幾個小塊湊起來的),求能夠分到的最大面積,精確到三位小數

解法

二分:
  雖然不是求什麼最大的最小值(或者反過來)什麼的……但還是可以用二分的,因爲之前就做過一道小數型二分題(下面等會講)
  考慮二分面積,下界L=0 ,上界R=ni=1πri2 。對於一箇中值x 和一張半徑爲r 的餅來說,這張餅能夠分出的最多分數顯然是:πr2x ,所以我們只需要求出ni=1πri2x ,判斷其與f+1 的關係即可
  特別要注意的一點:π的大小!!!,因爲r104 ,所以r2108 ,又因爲題目要求精確到三位小數,所以π 就要精確到10-11,即π=3.14159265358

拓展

maze

分析

  maze代碼:https://gitee.com/qjlyh/codes/dg3rbnm45xfz7ytjlckhu64
  maze數據:https://pan.baidu.com/s/1eS3Z9aq

複雜度

O(nlogRL

代碼

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<queue>
#define Lint long long int
using namespace std;
const double pi=3.141592653589;//79323846
const double eps=1e-6;
const int MAXN=10010;
double r[MAXN],s[MAXN];
double n,L,R;
int T,f;
bool check(double lim)
{
    int ret=0;
    for(int i=1;i<=n;i++)
        ret+=(int)(s[i]/lim);
    return ret>=f;
}
int main()
{
    scanf("%d",&T);
    while( T-- )
    {
        L=R=0;
        scanf("%lf%d",&n,&f),f++;
        for(int i=1;i<=n;i++)
        {
            scanf("%lf",&r[i]);
            s[i]=pi*r[i]*r[i];
            R+=s[i];
        }
        while( R-L>eps )
        {
            double mid=(L+R)/2;
            if( check( mid ) )   L=mid;
            else   R=mid;
        }
        printf("%.4lf\n",L);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章