算法竞赛入门经典训练指南打卡
题目链接:UVALive 3635
思路
就假定每个人得到的派的面积为x,然后进行判断
如果每个派分出来的派加起来大于等于f + 1个,则说明此时可以
使用二分查找找到最大的x即可
没有具体细节,逻辑简单
代码如下:
#include <iostream>
#include <cmath>
#define max_n 10000 + 5
#define ton(i , n) for(int i = 0 ; i < n ; ++ i)
using namespace std ;
const double PI = acos(-1.0) ;
int n , f ;
double pie[max_n] ;
bool OK(double M){
int sum = 0 ;
ton(i , n)
sum += floor(pie[i] / M) ; //sum统计如果分成面积为M的派。可以分成几个
return sum > f ;
}
int main(){
int t ;
cin >> t ;
while (t --){
cin >> n >> f ;
double R = - 1 ;
ton(i , n){
int r ;
cin >> r ;
pie[i] = PI * r * r ; //记录每个派的面积
R = max(R , pie[i]) ; //R存放最大的派的面积
}
double L = 0 ;
while (R - L > 1e-5){ //二分查找找到最大的结果
double M = (L + R) / 2 ;
if(OK(M))
L = M ;
else
R = M ;
}
printf("%.4lf\n" , L) ;
}
return 0 ;
}