ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 488|回复: 10

[分享] 分发糖果问题

[复制链接]

TA的精华主题

TA的得分主题

发表于 2023-12-8 13:29 | 显示全部楼层 |阅读模式
本帖最后由 shaowu459 于 2023-12-8 13:55 编辑

问题描述:

n(n为正整数) 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分,你需要按照以下要求,给这些孩子分发糖果
1)每个孩子至少分配到 1 个糖果。
2)相邻两个孩子评分更高的孩子会获得更多的糖果。
3)计算并返回需要准备的最少糖果数目 。

题目分析:

按照题目的分配原则,评分相同的孩子并不一定得到更多的糖果,每个孩子得到糖果的数量取决于这个孩子和其挨着的孩子评分比较结果。

假设孩子的评分数组是[1,3,2,2,1],则将按以下方式分配糖果:
1)每个孩子先获得一颗糖果,每个孩子分配的糖果初始数组[1,1,1,1,1]。
2)第一个孩子评分是1,比右侧孩子评分3低,所以第一个孩子仍保留一个糖果,糖果数组不变,仍为[1,1,1,1,1]。
3)第二个孩子评分是3,比左侧的1分和右侧的2分都高,所以这个孩子可以加一颗糖果(因为要准备最少得糖果),糖果数组变成[1,2,1,1,1]。
4)第三个孩子评分是2,比左侧的3低,并且也不比右侧的2高,因此,糖果数组保持不变,仍为[1,2,1,1,1]。
5)第四个孩子评分是2,不比左侧的2高,但是比右侧的1高,因此这个孩子多一个糖果,糖果数组变成[1,2,1,2,1]。
6)第五个孩子评分是1,比左侧的2低,所以糖果数组保持不变。
7)最后比较一下评分数组和糖果数组:
评分数组:[1,3,2,2,1]
糖果数组:[1,2,1,2,1]
相邻每一个评分高的孩子糖果数量都更高一些,满足了题目所有要求,所以[1,2,1,2,1]就是结果数组。
8)因为是从左到右遍历每个孩子得到的结果数组,所以遍历一遍后可能不满足题目要求,这时就需要从右侧再往左侧遍历一遍,规则相同。只要注意一点,当第n个孩子比第n+1个孩子评分高时,在第n+1个孩子糖果的数量基础上+1得到的结果如果比当前第n个孩子的糖果数量还小,就仍保持第n个孩子的糖果数量即可,也就是取MAX(第n个孩子已有糖果数量,第n+1个孩子糖果数量+1)的结果。

图片.png

分发糖果-超人.rar

13.93 KB, 下载次数: 8

评分

4

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-12-8 13:36 | 显示全部楼层
本帖最后由 shaowu459 于 2023-12-8 13:44 编辑

此题目目前已有多种不同的公式,本帖主要介绍我自己使用的公式,先贴上公式如下:
  1. =LET(v,A2:J2,f,LAMBDA(z,SCAN(,z,LAMBDA(x,y,IF(INT(y)>INT(x),MAX(INT(y)+MOD(x,1)+1%,y),y)))),SUM(--RIGHT(f(SORTBY(f(FILTER(v+1%,v<"")),-SEQUENCE(,COUNT(v)))),2)))
复制代码
图片.png


公式中使用的核心函数是SCAN函数,因为SCAN函数的x只能返回单值,所以一般只能保留一个信息。在上面的公式中,使用“整数+小数”的方式构造x,整数部分是孩子的评分,小数部分是该孩子的糖果数量,因此x同时保留了评分和糖果数量两种信息,在后续运算时分别提取x的整数部分和小数部分则可分别运算,运算完毕后,再将整数部分和小数部分合并更新x值。

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-12-8 13:43 | 显示全部楼层
SCAN函数部分运算的主要过程如下:

1)遍历包含评分和糖果数量的数组,第一个孩子直接进入x的初始值。
2)循环第二个值时,取当前x(第一个孩子的评分+糖果数量数值)的整数部分(评分)和当前循环值整数部分比较,如果当前孩子的评分高,则取当前孩子的糖果数量和前一个孩子的糖果数量+1两者的最大值作为当前孩子的糖果数量,然后作为新x的小数部分,加上当前y值的整数部分,形成新的x。
3)直至循环完毕。

因为可能要调用两次,所以把这个SCAN函数部分定义为一个自定义函数f:
图片.png

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-12-8 13:49 | 显示全部楼层
完整公式简要说明如下:

=LET(
    v, A2:J2,      源数据区域
    f, LAMBDA(z,   将SCAN函数运算定义为一个自定义函数f,以便重复调用
        SCAN(
            ,      省略一参,z的第一个值直接作为x的初始值,不参与LAMBDA函数体部分运算
            z,
            LAMBDA(x, y,
                IF(
                    INT(y) > INT(x),     如果当前孩子的评分大于前面一个孩子评分
                    MAX(INT(y) + MOD(x, 1) + 1%, y),     取前一个孩子糖果+1和当前孩子糖果数量较大者
                    y   如果当前孩子的评分不大于前面一个孩子,则保留糖果数量不变
                )
            )
        )
    ),
    SUM(
        --RIGHT(     因为直接使用MOD有浮点运算差,所以使用RIGHT函数取结果数组右侧两位(小数部分的糖果数量)再求和
            f(
                SORTBY(            从左到右遍历一遍后,将所有孩子倒序排列,再循环一次
                    f(FILTER(v + 1%, v < "")),   评分整数数组+0.01,给每个孩子先分一个糖果,然后调用f遍历
                    -SEQUENCE(, COUNT(v))
                )
            ),
            2
        )
    )
)

TA的精华主题

TA的得分主题

发表于 2023-12-8 14:17 | 显示全部楼层
利用整数部分和小数部分分别存储不同的结果。思路牛x。

TA的精华主题

TA的得分主题

发表于 2023-12-8 14:27 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2023-12-8 17:03 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2023-12-8 17:13 | 显示全部楼层
橒♂蝣 发表于 2023-12-8 17:03
有点难,但看来想成高手LAMBDA是必须要学好啊

这个题,就公式书写层面来说属于简单类的,我归到简单里了。题目本身分析出完整的解题思路难度比写公式要大一些。

TA的精华主题

TA的得分主题

发表于 2023-12-8 17:21 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
牛逼,学习了

TA的精华主题

TA的得分主题

发表于 2023-12-8 20:45 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
WPS逐步逐步的发布了新函数,例如textsplit在最新版的wps也有了,看来没办法要跟着shaowu版主的步伐向前进了。
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-5-10 15:30 , Processed in 0.042095 second(s), 14 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表