算法第二章上机实践报告

1.题目:派

2.题目描述:

我的生日要到了!根据习俗,我需要将一些派分给大家。我有N个不同口味、不同大小的派。有F个朋友会来参加我的派对,每个人会拿到一块派(必须一个派的一块,不能由几个派的小块拼成;可以是一整个派)。

我的朋友们都特别小气,如果有人拿到更大的一块,就会开始抱怨。因此所有人拿到的派是同样大小的(但不需要是同样形状的),虽然这样有些派会被浪费,但总比搞砸整个派对好。当然,我也要给自己留一块,而这一块也要和其他人的同样大小。

请问我们每个人拿到的派最大是多少?每个派都是一个高为1,半径不等的圆柱体。

输入格式:

第一行包含两个正整数N和F,1 ≤ N, F ≤ 10 000,表示派的数量和朋友的数量。 第二行包含N个1到10000之间的整数,表示每个派的半径。

输出格式:

输出每个人能得到的最大的派的体积,精确到小数点后三位。

输入样例:

3 3
4 3 3
 

输出样例:

在这里给出相应的输出。例如:

 25.133

3.算法描述:
二分法,从指定范围内进行类似二分查找的算法、直到找到满足条件为止

代码:

 1 #include <iostream>
 2 #include <cmath>
 3 using namespace std;
 4 
 5 const double PI=acos(-1.0);
 6 
 7 int find(double a[], int len, double mv){
 8     int ans=0;
 9     for(int j=0;j<len;j++){
10         ans+=int(a[j]/mv);
11     }
12     return ans;
13 }
14 int main(){
15     int n,f;
16     scanf("%d%d",&n,&f);
17     double v[n];
18     int b;
19     for(int j=0;j<n;j++){
20         scanf("%d",&b);
21         v[j]=b*b*PI;
22     }
23     double max=v[0];
24     for(int j=1;j<n;j++){
25         if(max<v[j]){
26             max=v[j];
27         }
28     }
29     double right=max;
30     double left=1;
31     double mid;
32     while((right-left)>1e-6){
33         mid=left+(right-left)/2;
34         if(find(v,n,mid)>=f+1){
35             left=mid;
36         }else{
37             right=mid;
38         }
39     }
40     printf("%.3f",mid);
41     return 0;
42 }

 

4.算法时间及空间复杂度分析(要有分析过程):

时间复杂度:类似二分查找 O (logN)  空间复杂度:O(1)

5.心得体会(对本次实践收获及疑惑进行总结):

条件判断一直没把握好,即便对了也没能很好的理解、一开始以为二分查找很容易、但一扩展、虽然修改的不多,却不便于理解

看来还是得多做题、要学好二分法还是挺难的接受的

 

 

 



 

posted @ 2020-10-10 22:53  詹迪明  阅读(231)  评论(0编辑  收藏  举报