arrays - 程序找出在 k 分钟过去之前将发生的交换次数
问题描述
给定 n 个在圆形轨道上运行的跑步者。每个跑步者在跨越另一个跑步者时,他们交换宝石。给定一个包含每个跑步者完成循环轨道所用时间(以分钟为单位)的数组和一个整数 k。我们需要找出在 k 分钟过去之前将发生的交换次数。
[编辑 1]:我认为使用所有数字的 hcf 作为会面点,但无法通过。你能帮忙的话,我会很高兴。
解决方案
我对这类问题的回答通常是先自己尝试一下,但这是一个非常困难的问题,所以我要给你解决方案。
我们在这里要做的是计算一个跑步者超越另一个跑步者的次数。首先,我们可以按照跑步者的速度对跑步者进行排序,这稍后会派上用场。对于第i
th 跑者,我们可以很容易地计算出他们将跑的圈数,我将其称为L(i)
。对于两个跑步者来说i
,j
哪里比哪里i
快,通过j
的次数是。我们的解决方案是所有和where对的这个值的总和。i
j
floor(L(i) - L(j))
i
j
i > j
如果限制n
足够小,您可以遍历所有这些对并及时总结这些值O(n^2)
。但是如果n
很大,这将太慢。如果我们只是想在没有底函数的情况下计算L(i) - L(j)
所有的总和i > j
,我们可以使用前缀总和在线性时间内完成。
如果我们的跑步者n - 1
按照他们的速度顺序从 0 到编号,对于 的每个值,所有小于的值的i
总和等于,其中是总和的预计算值。现在我们需要处理地板功能。对于两个实数,其中,如果 的小数部分大于或等于 的小数部分,则等于,否则。L(i) - L(j)
j
i
L(i) * i - P(i - 1))
P(j)
L(0) + L(1) + L(2) + ... + L(j)
x
y
x > y
floor(x - y)
floor(x) - floor(y)
x
y
floor(x) - floor(y) - 1
因此,如果我们需要计算一个跑步者i
超过另一个跑步者的次数,我们可以首先使用上面描述的前缀和技术计算每个L
值的下限,然后减去j
小数部分L(j)
大于的值的数量的小数部分L(i)
。找到j
小数部分L(j)
大于小数部分的值的数量L(i)
基本上是对实数进行倒数计数,这可以通过二叉索引树来完成。
最后的复杂度是O(n log n)
。
推荐阅读
- postgresql - 如何使用 jpa 标准检查 postgresql jsonb 列中存在的元素?
- excel - 隐藏范围内除单元格值外的所有列
- python - 为什么 elif 在我的 Python 示例中不起作用?
- java - 尝试使用 CameraX 和 MLKit 构建条形码扫描仪,但在 BarcodeScanning.getClient() 出现“MlKitContext 尚未初始化”异常
- powershell - 进行比较时,Powershell 脚本已经运行了好几天
- node.js - yargs.command 不起作用(错误消息:yargs.command 不是函数)
- list - 有什么办法可以解决这个错误:IndexError: list index out of range
- php - 警告:需要(./wp-blog-header.php):无法打开流:第 17 行的 /home/newapropos/public_html/index.php 中没有这样的文件或目录
- vb.net - 如何在 vb.net 中的树视图的节点上创建工具提示?
- c++ - C++ 无法打印字符串数组中的值