这题很好做,使用二分法就OK。

首先在读取所有派的半径后处理出所有派的面积,并且记录最大的那个派的面积。然后从 0 ~ maxsize 二分枚举一下,就能得到答案。

此外,这道题最后输出保留小数位数可以是 3, 4, 5,都可以。

附AC代码:

   1: #include <stdio.h>
   2: #include <math.h>
   3: #include <iostream>
   4: #include <cstdarg>
   5: #include <algorithm>
   6: #include <string.h>
   7: #include <stdlib.h>
   8: #include <string>
   9: #include <list>
  10: #include <vector>
  11: #include <map>
  12: #define LL long long
  13: #define M(a) memset(a, 0, sizeof(a))
  14: using namespace std;
  15: void Clean(int count, ...)
  16: {
  17:     va_list arg_ptr;
  18:     va_start (arg_ptr, count);
  19:     for (int i = 0; i < count; i++)
  20:         M(va_arg(arg_ptr, int*));
  21:     va_end(arg_ptr);
  22: }
  23:  
  24: const double PI = acos(-1.0);
  25: double buf[10009];
  26: int n, f;
  27:  
  28: bool Deal(double size)
  29: {
  30:     int res = 0;
  31:     for (int i = 1; i <= n; i++)
  32:         res += floor(buf[i] / size);
  33:     return (res >= (f + 1));
  34: }
  35:  
  36: int main()
  37: {
  38:     int T;
  39:     scanf("%d", &T);
  40:     while (T--)
  41:     {
  42:         double m = -1;
  43:         scanf("%d%d", &n, &f);
  44:         for (int i = 1; i <= n; i++)
  45:         {
  46:             int r;
  47:             scanf("%d", &r);
  48:             buf[i] = PI * r * r;
  49:             m = max(m, buf[i]);
  50:         }
  51:         double tmp = 0.0;
  52:         while (m - tmp > 1e-5)
  53:         {
  54:             double p = (m + tmp) / 2.0;
  55:             if (Deal(p)) tmp = p;
  56:             else m = p;
  57:         }
  58:         printf("%.5lf\n", tmp);
  59:     }
  60:     return 0;
  61: }

05-04 00:15