説明文
私の誕生日が近づいてきており、伝統的にパイを提供しています。パイが1つだけではなく、いいえ、私はそれらの数N、さまざまな味とさまざまなサイズを持っています。私の友人のFが私のパーティーに来ており、彼らのそれぞれがパイの切れ端を受け取ります。乱雑に見えるので、これは1つのパイの1つのピースであり、いくつかの小さなピースではありません。ただし、このピースは1つの丸いパイになる場合があります。
私の友人は非常に迷惑であり、彼らの1人が他の人よりも大きな作品を受け取った場合、彼らは不平を言い始めます。したがって、一部のパイが台無しになることになっても(パーティーを台無しにするよりはましです)、すべてが同じサイズ(ただし必ずしも同じ形ではない)のピースを取得する必要があります。もちろん、私も自分用にパイが欲しいので、そのピースも同じサイズにする必要があります。
私たち全員が取得できる最大のピースサイズは何ですか?すべてのパイは円筒形で、すべて同じ高さ1ですが、パイの半径は異なる場合があります。
入力
1≤N、F≤10 000の2つの整数NとFを持つ1行:パイの数と友達の数。
N整数riが1≤ri≤10 000の1行:パイの半径。
アウトプット
私と私の友達全員がサイズVのパイ片を取得できるように、最大のボリュームVを持つ1行を出力します。答えは、小数点以下3桁に丸められた浮動小数点数として与えられる必要があります。
入力例
3 3
4 3 3
出力例
25.133
解決策
#include <iostream>
#include <iomanip>
#include <cmath>
#include <algorithm>
using namespace std;
#define eps 1e-5
double pi=acos(-1.0); // 圆周率π=arcos(-1)
double a[100005];
int n=0, f=0;
bool judge(double mid) {
int cnt=0; // 合格的派计数器
for (int i=0; i<n; i++)
cnt+=floor(a[i]/mid); // 派的面积合格,则计数器增加
return cnt>=f+1; // 自己的1份
}
double binarysearch() {
double l=1, r=a[n-1];
do {
double mid = l + (r-l)/2;
if (judge(mid)) l = mid;
else r = mid;
} while (fabs(r-l)>eps); // 浮点数二分搜索
return l;
}
int main() {
cin >> n >> f;
for (int i=0; i<n; i++) {
cin >> a[i];
a[i] = a[i]*a[i]*pi; // 更新数组为派的面积
}
sort(a,a+n); // 排序
cout << fixed << setprecision(3) << binarysearch() << endl;
return 0;
}