算法第二章作业
2-5 派 (15分)
我的生日要到了!根据习俗,我需要将一些派分给大家。我有N个不同口味、不同大小的派。有F个朋友会来参加我的派对,每个人会拿到一块派(必须一个派的一块,不能由几个派的小块拼成;可以是一整个派)。
我的朋友们都特别小气,如果有人拿到更大的一块,就会开始抱怨。因此所有人拿到的派是同样大小的(但不需要是同样形状的),虽然这样有些派会被浪费,但总比搞砸整个派对好。当然,我也要给自己留一块,而这一块也要和其他人的同样大小。
请问我们每个人拿到的派最大是多少?每个派都是一个高为1,半径不等的圆柱体。
输入格式:
第一行包含两个正整数N和F,1 ≤ N, F ≤ 10 000,表示派的数量和朋友的数量。 第二行包含N个1到10000之间的整数,表示每个派的半径。
输出格式:
输出每个人能得到的最大的派的体积,精确到小数点后三位。
输入样例:
3 3
4 3 3
输出样例:
在这里给出相应的输出。例如:
25.133
算法描述:
//#pragma GCC optimize(3) #include <bits/stdc++.h> using namespace std; #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define inf 0x3f3f3f3f #define INF 0x7fffffff #define infll 0x3f3f3f3f3f3f3f3f #define il inline #define re register #define pb push_back #define db double #define ll long long #define ull unsigned long long #define pii pair<int,int> #define pll pair<ll,ll> #define puu pair<ull,ull> #define MP make_pair #define lowbit(x) x&(-x) #define fi first #define se second il ll read() { char ch = getchar(); ll p = 1,data = 0; while(ch<'0'||ch>'9') { if(ch == '-')p = -1; ch = getchar(); } while(ch>='0'&&ch<='9') { data = data*10+(ch^48); ch = getchar(); } return p*data; } il ll qpow(ll a,ll b) { ll r = 1; while(b) { if(b&1)r = a*r; a = a*a; b>>=1; } return r; } il ll gcd(ll a,ll b) { if(!a || !b) return (!a)?b:a; while(b ^= a ^= b ^= a %= b); return a; } il ll lcm(ll a,ll b) { return a*b/gcd(a,b); } void exgcd(ll a, ll b, ll &x,ll &y) { if(!b) x = 1, y = 0; else { exgcd(b, a % b, y, x); y -= x * (a / b); } } const int mod = 1e9+7,maxn = 1e4+5; #define PI acos(-1) #define eps 1e-4 db a[maxn]; int n,f; int check(db x) { int num = 0; for(int i = 1; i <= n; i++) num += floor(a[i]/x); return num >= f+1; } int main() { n = read(),f = read(); for(int i = 1; i <= n; i++) a[i] = read(),a[i] = a[i]*a[i]*PI; db l = 0.0,r = 1e9,mid,ans = 0.0; while(r-l >= eps) { mid = (l+r)/2; if(check(mid)) l = mid,ans = mid; else r = mid; } printf("%.3lf\n",ans); return 0; }
算法时间及空间复杂度分析:
通过二分答案O(logn),然后用check函数来O(n)检测是否能满足此时所分的派的大小。
总时间复杂度O(nlogn)
空间复杂度需要O(n)的数组,总复杂度为O(n)
心得体会:
本题用二分来做以及check函数并不难想到,但上机的时候因为把圆的面积公式记成了PI*r*r/2而导致卡了一段时间,实在不应该。