题目链接:https://vjudge.net/problem/POJ-3122
题目大意:你有n个不同大小的派要分给若干个人,每个人分得大小都要一样而且不能有某个人的派是几个不同的派拼成的情况
思路很简单,只要在0~和所有派的面积平均值之间二分最大值就可以了
#include<set> #include<map> #include<stack> #include<queue> #include<cmath> #include<stdio.h> #include<cctype> #include<string> #include<vector> #include<climits> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define endl '\n' #define max(a, b) (a > b ? a : b) #define min(a, b) (a < b ? a : b) #define mst(a) memset(a, 0, sizeof(a)) #define _test printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n") using namespace std; typedef long long ll; typedef pair<int, int> P; const double pi = acos(-1.0); const double eps = 1e-7; const int INF = 0x3f3f3f3f; const int _NAN = -0x3f3f3f3f; const int maxn = 1e4+10; double arr[maxn]; double solve (double l, double r, int n, int f) { double mid = (l+r)/2.0; if (fabs(l-r) <= eps) return mid; int cnt = 0; for (int i = 0; i<n; ++i) cnt += floor(arr[i]/mid); //统计面积为mid时可以分出多少块派 return cnt >= f ? solve(l, mid, n, f) : solve(mid, r, n, f); //二分求使cnt >= f的最大面积 } int main(void) { int t; scanf("%d", &t); while(t--) { int n, f; scanf("%d%d", &n, &f); ++f; double num, sum = 0; for (int i = 0; i<n; ++i) { scanf("%lf", &num); arr[i] = num*num; sum += arr[i]; } printf("%.4f\n", solve(sum/f, 0, n, f)*pi); } return 0; }