2。問題の説明
私の誕生日は来ています!カスタムによると、私はあなたにいくつかのパイを与える必要があります。私はNさまざまな味、パイの大きさが異なります。F私のパーティーに来る友人を持って、誰もがパイを取得します(必须一个派的一块,不能由几个派的小块拼成
;全体のパイすることができます)。
私の友人は誰かが大きな部分を得た場合、文句を開始します、特にけちです。因此所有人拿到的派是同样大小的
この派閥のいくつかは、より良い全体のパーティーまで良いネジよりも無駄にされますが、が、(しかし、同じ形状である必要はありません)。もちろん、私は自分自身に1を与える必要があり、この1は同じ大きさなどをする必要があります。
私はパイ最大の数である得るために私達のそれぞれを頼みますか?各高校1、シリンダに至るまで半径です。
エントリー
最初の行は、2つの正の整数NとF、1≤N、F≤10 000を含んで、数は友人や学校の数を示します。
第二行は、各派閥の半径を表し、N 1から10000の間の整数を含んでいます。
輸出
各人の出力は、最大音量派を得ることができます精确到小数点后三位
。
输入样例
3 3
4 3 3
输出样例
25.133
----二分法のポイントパイ
次のようにアイデアがあります
質問の意味:あなたのパイを与えるN、M + 1人、各パイの高さと同じ、しかし、彼らは異なる半径を持っている、し
たが、M + 1の個々の非常にうるさい、各サブパイがブロックに分割されなければならない唯一のnから来ることができますパイここで
アイデア:この質問は、単純な二分法である、私は,,,,,,,半分に分子パイの値を仮定して、正確にこれを縮小し、その後、サブパイ半ばとその全員のポイントを想定し、?このように、私たちは必要な値を得ることができ
、この質問は、アイデアも参照することができ、問題と同様の問題を
問題を解決するため、以下のように
#include<iostream>
#include<cmath>
using namespace std;
const double pi = acos(-1); //求圆周率
const int Len = 10005;
const double cha = 0.00001; //⚠️精读尽量开大一点,防止出错
int n,m;
int ar[Len];
double ans; //每个人所能分的最大子pie的大小
bool judge(double mid)
{
int m_cnt = m; //总共需要分割的数量
for(int i = 1; i <= n; i ++)
{
double V = pi * ar[i] * ar[i];
if(V >= mid)
{
m_cnt -= int(V / mid);
}
if(m_cnt <= 0)
{
return true;
}
}
return false;
}
void Binary_search(double l ,double r)
{
while(r - l > cha)
{
double mid = (l + r) / 2;
if(judge(mid)) //如果我这个假设的 子pie的大小mid,是可以完全由 n 张 pie 分割出来,那么我们要考虑 能不能把 假设子pie大小mid 调大一些(通过调整下限 mn = mid),这样再进行尝试
{
ans = mid;
l = mid;
}
else //不能够分割出来m块大小为 mid的子pie,那么我们就缩小,mid值(通过调整 上线mx = mid)
{
r = mid;
}
}
printf("%.3lf\n",ans);
}
int main()
{
//freopen("T.txt","r",stdin);
scanf("%d %d", &n, &m);
m ++; //包括自己,所以总人数 + 1
for(int i = 1; i <= n; i ++)
scanf("%d",&ar[i]);
Binary_search(0 , pi * Len * Len);
return 0;
}