充电 | ||||||
| ||||||
Description | ||||||
玻璃小屋内有n个插排,屋内有 m 个需要供电的机器,并且墙上有k个可以直接使用的插口。知道了每个插排上的插口的个数,并且所有的插头和插口都是可以匹配的。问你最少用几个插排可以让所有机器都供上电?
| ||||||
Input | ||||||
多组测试数据,每组第一行输入n, m, k。(1 ≤ n, m, k ≤ 50) 第二行有n个数,分别表示每个插排上插口的个数。 | ||||||
Output | ||||||
输出最少需要几个插排。如果有电器无法充上电则输出-1。 每组输出占一行。 | ||||||
Sample Input | ||||||
3 5 3 3 1 2 4 7 2 3 3 2 4 5 5 1 1 3 1 2 1
| ||||||
Sample Output | ||||||
1 2 -1 | ||||||
Author | ||||||
曾卓敏 @hrbust
|
思路:
把插排按照插口数从大到小排序,然后从1~min(n,k)扫一遍,用一个sum变量一直加a【i】(插口数),一边判断sum是否能够大于m,一边判断sum+剩下的墙上的插口数能否大于m。
如果上述判断并不能满足m的需求,那么再判断插排连接插排的情况即可、
AC代码;
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[121];
int main()
{
int n,m,k;
while(~scanf("%d%d%d",&n,&m,&k))
{
memset(a,0,sizeof(a));
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
a[0]=0;
sort(a+1,a+n+1);
reverse(a+1,a+n+1);
int sum=0;
int ok=0;
int i;
for(i=0;i<=n&&i<=k;i++)//没有插座和插座相连的时候。
{
sum+=a[i];
if(sum>=m)
{
ok=1;
printf("%d\n",i);
break;
}
else if(sum+k-i>=m)
{
ok=1;
printf("%d\n",i);
break;
}
}
if(ok==0)
{
int ok2=0;
for(int j=i;j<=n;j++)
{
sum+=a[j]-1;
if(sum>=m)
{
ok2=1;
printf("%d\n",j);
break;
}
}
if(ok2==0)
{
printf("-1\n");
}
}
}
}