小猴编程6月公开赛普及组 --- 第2题采摘香蕉
Posted elisa02
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了小猴编程6月公开赛普及组 --- 第2题采摘香蕉相关的知识,希望对你有一定的参考价值。
这道题因为我还没有通过,只能展示我15分的代码,如果有人能明白我错在哪里,请务必告诉我修正过来,谢谢
如果你希望得到的是正确的AC的代码,这个文章可能并不能帮助你,很抱歉
2020.6.25
一、题目描述
又到了猴村香蕉成熟的季节,小猴子们争先恐后地来采摘香蕉。
所有香蕉都长在树上,离地高度不一。
如果小猴子跳起来能达到的高度大于等于香蕉的高度,那他就可以采摘到这根香蕉。
公平起见,猴博士打算让跳得低的小猴子先摘,跳得高的小猴子后摘。
假设每只小猴子都会在轮到自己的时候,把他所能够着的香蕉全部摘下来。
现在,已知每只小猴子跳起来能达到的高度,以及每根香蕉的离地高度,你能统计出每只小猴子能够采摘到的香蕉数量吗?
【输入格式】
第一行,包含两个用空格分隔的正整数n和m,分别表示小猴子的数量和香蕉的数量。
第二行,包含n个用空格分隔的正整数a[i],两两不同,依次表示每只小猴子跳起来能达到的高度。
第三行,包含m个用空格分隔的正整数h[i],依次表示每根香蕉的离地高度。
【输出格式】
一行,包含n个整数,按输入顺序依次表示每只小猴子能够采摘到的香蕉数量。相邻两数之间用单个空格分隔。
【输入样例】
3 7
46 18 26
39 74 13 9 20 18 45
【输出样例】
2 3 1
【样例说明】
首先,让跳起来只能达到高度18的小猴子采摘香蕉。他能采摘到高度为13、9、18的共3根香蕉。
接着,让跳起来只能达到高度26的小猴子采摘香蕉。此时,他只能采摘到高度为20的共1根香蕉。
最后,让跳起来只能达到高度46的小猴子采摘香蕉。此时,他能采摘到高度为39、45的共2根香蕉。
【数据规模】
对于50%的数据,保证1 ≤ n, m ≤ 1000。
另有30%的数据,保证1 ≤ a[i], h[i] ≤ 107。
对于100%的数据,保证1 ≤ n,m ≤ 106,1 ≤ a[i],h[i] ≤ 109,且a[i]两两不同。
二、解题思路
预处理a[i]和h[i],将他们按照数值从小到大排序,然后依次为每一个a[i]计算答案
具体地,对于每一个a[i],均为其在排序后的h[i]中找到最后一个小于等于a[i]的数的下标p[i]
特殊处理:将p[0] = 0, 则易得到a[i]所对应的答案为p[i] - p[i-1],因为p[i-1]代表的是最后一个小于等于a[i-1]的数的下标
正因为第i-1只小猴子把他能够到的香蕉都摘下来了,所以第i只猴子肯定是得从上一只小猴子摘下的最后一个香蕉再+1的香蕉开始摘。
第几步(步) | 干什么 |
1 | 输入a[i] |
2 | 输入banana[i](在题目中是h[i]) |
3 | 将a[i]从小到大排序 |
4 | 将banana[i]从小到大排序 |
5 | 求出p |
那么问题来了:怎么求出p,还只能使用一层for循环
我推荐使用一个函数:upper_bound(数组开始的下标,数组结束的下标,查找的数(后面用val表示) ) - 数组名
这个函数的作用是查找固定的数组中大于等于我查找的val的下标,可是我们查找的是小于等于
我们虽然返回的是大于val的下标,可是我们已经将这个数组排过序了,直接-1就能成为小于等于了
三、代码描述
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; long long place, n, m, banana[10000000], max_tmp; struct monkey{ long long b;//跳得高度 long long array;//旧的下标 long long num;//能摘到的桃子的数量 long long p;//在banana的范围内最后一个小于等于a[i]的下标 }a[10000000]; bool cmp(monkey x, monkey y){//按照跳的高度来排序 return x.b < y.b; } bool cmp2(monkey x, monkey y){//按照原来输入的顺序来排序 return x.array < y.array; } int main(){ cin >> n >> m; for(long long i = 1;i <= n;i++){ cin >> a[i].b; a[i].array = i; } sort(a+1, a+n+1, cmp);//按照跳的高度来排序 for(long long i = 1;i <= m;i++){ cin >> banana[i]; } sort(banana+1, banana+m+1); for(long long i = 1;i <= n;i++){ a[i].p = (upper_bound(banana, banana+m, a[i].b) - banana) - 1; //upper_bound(开始的下标,结束的下标,查找的量)-数组名称 //以上是固定写法 //upper_bound()原来是返回大于我要查找的量的下标 //可是我要求的是小于等于的下标,所以要-1 } a[0].p = 0; for(long long i = 1;i <= n;i++){ a[i].num = a[i].p - a[i-1].p; } sort(a+1, a+n+1, cmp2);//按照原来输入的顺序来排序 for(int i = 1;i <= n;i++){ cout << a[i].num << ‘ ‘; } return 0; }
以上是关于小猴编程6月公开赛普及组 --- 第2题采摘香蕉的主要内容,如果未能解决你的问题,请参考以下文章