day8--Bookshelf B--1.30
习题概述
题目描述
Farmer John 最近为奶牛们的图书馆添置了一个巨大的书架,尽管它是如此的大,但它还是几乎瞬间就被各种各样的书塞满了。现在,只有书架的顶上还留有一点空间。
所有(1≤N≤20,000) N头奶牛都有一个确定的身高Hi(1≤Hi≤10,000)。设所有奶牛身高的和为S。书架的高度为B,并且保证1≤B≤S<2,000,000,007。
为了够到比最高的那头奶牛还要高的书架顶,奶牛们不得不像演杂技一般,一头站在另一头的背上,叠成一座“奶牛塔”。当然,这个塔的高度,就是塔中所有奶牛的身高之和。为了往书架顶上放东西,所有奶牛的身高和必须不小于书架的高度。
显然,塔中的奶牛数目越多,整座塔就越不稳定,于是奶牛们希望在能够到书架顶的前提下,让塔中奶牛的数目尽量少(身高 高的先上)。 现在,奶牛们找到了你,希望你帮她们计算这个最小的数目。
输入格式
第 1 行: 2 个用空格隔开的整数:N 和 B;
第 2…N+1 行: 第 i+1 行是 1 个整数:Hi。
输出格式
第 1行: 输出 1个整数,即最少要多少头奶牛叠成塔,才能够到书架顶部。
代码部分
#include<bits/stdc++.h>
using namespace std;
int high[20005];//数组high 存储奶牛身高
bool cmp(int a,int b)//自定义比较函数从大到小
{return a>b;
}
int main()
{int n,b;//n表示奶牛数量,b表示书架高度 cin>>n>>b;for(int i=0;i<n;i++)//循环读取每头奶牛的身高 {cin>>high[i];}sort(high,high+n,cmp);//sort变为从大到小排序 int sum=0,ans=0;//表示当前奶牛塔的总高度和塔中奶牛的数量 while(sum<b)//只要高度不够就继续叠{sum+=high[ans];ans++;}cout<<ans;return 0;
}
心得体会
1.这个习题要求计算最少需要多少头奶牛才能够使它们的身高之和达到或超过给定的书架高度。
解决这个问题的思路:先将奶牛的身高从大到小进行排序,然后从最高的奶牛开始累加身高,直到累加的身高达到或超过书架的高度。通过计数器记录累加的奶牛数量,最后输出计数器的值即为最少所需的奶牛数量。
2.在C++标准库中,sort
函数默认是按升序进行排序的。但本题需要按照奶牛的身高从大到小进行排序,以便从最高的奶牛开始叠加身高按降序排序,所以使用sort
函数结合自定义的比较函数cmp来实现。
3.如果不想使用自定义函数那么需要有几处修改为
sort(high, high + n);
sum += high[n - 1 - ans]; ans++;
解释:
sum += high[n - 1 - ans]
的语句时,在每次循环中将数组 high
中的最后一个元素(即最大的身高,此时是利用sort所排的升序)添加到 sum
中。n
是奶牛的数量,而 ans
是一个计数器,表示已经叠加的奶牛的数量。
为了从最高的奶牛开始叠加身高,因为数组 high
在经过排序后最后一个元素(即 high[n - 1]
)代表的是最大的身高。所以 n - 1 - ans
来访问数组 high
的最后一个元素。
ans++
会将计数器 ans
的值增加 1,以便在下一轮循环中继续叠加下一个身高。
下面是更改后的代码:(代码看似简单,但需要仔细考虑)
#include<bits/stdc++.h>
using namespace std;
int high[20005]; // 数组high 存储奶牛身高
int main()
{int n, b; // n表示奶牛数量,b表示书架高度cin >> n >> b;for(int i = 0; i < n; i++) // 循环读取每头奶牛的身高{cin >> high[i];}sort(high, high + n); // sort默认升序排序int sum = 0, ans = 0;while(sum < b) // 只要高度不够就继续叠{sum += high[n - ans - 1];ans++;}cout << ans;return 0;
}