算法第二章作业

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而导致卡了一段时间,实在不应该。

 
posted @ 2020-10-31 22:58  Frantatic  阅读(153)  评论(0编辑  收藏  举报