程序以查找直到经过k分钟后的交换次数

时间:2018-08-01 15:45:11

标签: arrays algorithm

给出n个在圆形轨道上奔跑的跑步者。每个跑步者穿过另一个跑步者时,都会交换宝石。给定每个跑步者完成循环轨迹所花费的时间(以分钟为单位)的数组和整数k。我们需要找到在经过k分钟之前进行的交换次数。

[编辑1]:我考虑过使用所有数字的hcf作为交汇点,但是无法通过。任何帮助都很好。

1 个答案:

答案 0 :(得分:1)

我对这类问题的回答通常是先自己尝试一下,但这是一个非常困难的问题,所以我将为您提供解决方案。

我们在这里要做的是计算一个跑步者超越另一个跑步者的次数。首先,我们可以根据跑步者的速度对他们进行排序,这将在以后派上用场。对于第i名跑步者,我们可以轻松地计算出他们将跑的圈数,我将其称为L(i)。对于ij快的两个跑步者iji通过j的次数是{{1} }。我们的解决方案是所有floor(L(i) - L(j))i对,其中j的所有值的总和。

如果i > j的限制足够小,则可以遍历所有这些对,并在n时间内求和。但是,如果O(n^2)大,则速度太慢。如果我们只想计算所有n的{​​{1}}的总和而没有下限函数,则可以使用前缀总和在线性时间内完成。

如果我们的跑步者按照速度顺序从0到L(i) - L(j)进行编号,则对于i > j的每个值,对于n - 1的所有值,i的总和小于L(i) - L(j)等于j,其中iL(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)的数量基本上是对实数的inversion counting,这可以通过二进制索引来完成树。

最终的复杂度为L(i)