Description
Windbreaker计划送一些项链给他的朋友们作为新年礼物。为了表示诚意,他决定自己制作全部的项链。他购买了若干种珍珠,每种珍珠都有特定的颜色。他要制作的项链都是M-完美的,也就是每条项链都是恰好由M种珍珠组成的。Windbreaker想知道他最多能送出多少条项链。给定每种珍珠的数目,你要回答的是Windbreaker最多可以制作多少条M-完美项链。
Input
输入包含多组测试数据。每组数据第一行是一个正整数n,代表有n种珍珠。第二行包含n个正整数,代表每种珍珠的数目。第三行包括1个正整数M,代表要制作的是M-完美项链。 输入数据以1行n=0结束。这组数据不用处理。
Output
对每组测试数据,输出一行答案,为一个整数,代表最多能制作的M-完美项链的数目。
Sample Input
5 3 3 3 3 3 5 6 1 2 3 4 5 6 5 0
Sample Output
3 3
Data Constraint
对20%的数据,有n<=10;
对40%的数据,有n<=100;
对100%的数据,有n<=1000,每种珍珠数目不超过2000,1<=M<=100。
.
.
.
.
.
.
分析
二分答案。
每次二分,如果最大m种珍珠数不够当前的mid就从其他珍珠里面借。如果能凑齐m种珍珠每种数量为mid的就可以了。
.
.
.
.
.
.
程序:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,a[2000],m;
bool check(int x)
{
int tj=0;
for (int i=1;i<=n-m;i++)
tj+=a[i];
for (int i=n-m+1;i<=n;i++)
if (a[i]<x)
{
tj-=x-a[i];
if (tj<0) return false;
}
return true;
}
int ef(int l,int r)
{
while (l<r)
{
int mid=(l+r+1)/2;
if (check(mid)==true) l=mid; else r=mid-1;
}
return l;
}
int main()
{
while (scanf("%d",&n),n!=0)
{
if (n==0) break;
memset(a,0,sizeof(a));
int sum=0;
for (int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
sum+=a[i];
}
scanf("%d",&m);
sort(a+1,a+n+1);
int ans;
ans=ef(0,sum/m);
printf("%d
",ans);
}
return 0;
}