一,题意:
有f+1个人(包括自己),n块披萨pie,给你每块pie的半径,要你公平的把尽可能多的pie分给每一个人
而且每个人得到的那份pie必须是从同一个pie上得到的,不能拼凑,多余的边角丢掉。
二,思路:
1,输入,并找出最大体积的pie
2,二分法记录每一种情况的体积,及能分给几个人,
贪心的思想:
先取能分给n-1个人的最大体积,逐渐减少每份pie的体积
直到最接近n个人都能获得的pie的最大的体积
3, 输出。
三,步骤:
1,输入,max存储最大的pie体积
2,二分法:
i,退出条件max-min <= 1e-6;
由n-1个人体积慢慢减少,逐渐接近n个人的体积,
最后mid存储的pie体积即为每个人分得的最大体积。
ii,count记录pie能分的份数
iii, 如果份数 < 人数,减少每份pie的体积,即max = mid ; mid = (min+max)/2;
否则,增加每份pie的体积,即min = mid ; mid = (min+max)/2;
3,输出:注意控制输出的小数位数。
setprecision、fixed、showpoint的用法总结:
1 #include<iostream> 2 #include<iomanip> 3 using namespace std; 4 const double PI = 3.14159265359; //这是最短的PI长度,再短就WA了 5 const double esp = 1e-6; //为了double二分法设定的最小精度限制值 6 double pie[10050]; 7 8 int main(){ 9 int t , n , f; //n表示一开始pie的份数,f表示朋友的人数 10 cin>>t; 11 while(t--){ 12 cin>>n>>f; 13 f++; //人数加上自己 14 double max = 0.0; 15 for(int i = 0 ; i < n ; i++){ 16 cin>>pie[i]; 17 pie[i] *= pie[i]; ////半径平方,计算pie的体积时先不乘PI,为了提高精度和减少时间 18 if(max<pie[i]) 19 max = pie[i]; //记录最大pie的体积 20 } 21 double min = 0.0 ; //注意改为0,会出错 22 double mid ; 23 while(max-min>esp){ //实数double的二分结束条件不同于整数int的二分结束条件 24 mid = (min + max)/2; 25 int count = 0 ; //记录根据不同的mid尺寸能分多少份数 26 for(int i = 0 ; i < n ; i++){ 27 count += (int)(pie[i]/mid);//第i个pie按照mid的尺寸去切,最多能分的人数(取整) 28 } 29 if(count < f) max = mid ; //mid偏大 30 else min = mid ; //mid偏小 31 // cout<<count<<"-"<<mid<<" "; //输出一下,你会发现其中的奥妙。 32 } 33 cout<<fixed<<setprecision(4)<<PI*mid<<endl;//fixed与setprecision配合使用规定小数点后的位数 34 } 35 return 0; 36 }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-08-09 15:17:57