小猴编程6月公开赛普及组 --- 第2题采摘香蕉

这道题因为我还没有通过,只能展示我15分的代码,如果有人能明白我错在哪里,请务必告诉我修正过来,谢谢

如果你希望得到的是正确的AC的代码,这个文章可能并不能帮助你,很抱歉

2020.6.25

原题网站:https://jingsai.xiaohoucode.com/?id=38#/studentComplier?bundleId=01729ce53bae00163e0979d7002c0001&back=%2F48

官方解析网站:https://mp.weixin.qq.com/s?__biz=MzUxNzE2MDAxOA==&mid=2247484565&idx=4&sn=fd71dfac3bdffcf4c669f99c9b58e3f2&chksm=f99d29a8ceeaa0bef0f60bddb2cba13e0d8b5f999f4835c1676732306e64173936f9658ee2a4&mpshare=1&scene=1&srcid=&sharer_sharetime=1593013541145&sharer_shareid=e0f1ceb04b3723d4fc7fbf294bf132ee&exportkey=ARPQkdmQFjz9JcpC%2FWYkXJI%3D&pass_ticket=OS%2BEffpn5TN2bzeYTHWx3VrjdGamPcnoVtOeXoZi7%2BeN4pCRdqur7sAjXxPJbc9n#rd

一、题目描述

又到了猴村香蕉成熟的季节,小猴子们争先恐后地来采摘香蕉。
所有香蕉都长在树上,离地高度不一。
如果小猴子跳起来能达到的高度大于等于香蕉的高度,那他就可以采摘到这根香蕉。
公平起见,猴博士打算让跳得低的小猴子先摘,跳得高的小猴子后摘。
假设每只小猴子都会在轮到自己的时候,把他所能够着的香蕉全部摘下来。
现在,已知每只小猴子跳起来能达到的高度,以及每根香蕉的离地高度,你能统计出每只小猴子能够采摘到的香蕉数量吗?

【输入格式】

第一行,包含两个用空格分隔的正整数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] ≤ 10 7
对于100%的数据,保证1 ≤ n,m ≤ 10 6 ,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;
}

猜你喜欢

转载自www.cnblogs.com/elisa02/p/13191248.html