我在网上发现了以下问题,并对在Haskell中解决这个问题很感兴趣。
给了钱X泰铢和N人,我们将分配资金如下.第一轮:给予第一个人1泰铢,第二个人得到2泰铢,.,第N个人得到N泰铢。如果钱(X -分配的钱)仍然剩余,那么我们将再次分配它。所以...第二回合:给予第一个人2泰铢,第二个人3泰铢,.,第N个人得到N+1泰铢。第三回合:给予第一个人3泰铢,第二个人4泰铢,.,第N个人N+2泰铢。
我们会把钱分发出去,直到它用完为止。然后输出是每个人得到的一组钱。
举例来说:输入:x = 21(泰铢)和n = 5(作为人头数)。第一轮,每个人将获得的钱为{1, 2, 3, 4, 5}
第二轮,每个人将获得的钱为{2, 3, 1, 0, 0}
最后,输出将是{3, 5, 4, 4, 5}
问题是如何在Haskell中实现这一点,并且最好在 O(n) 时间内实现。
1条答案
按热度按时间7lrncoxx1#
我们要解决的第一个问题是知道我们可以完全填充多少轮,以及我们还需要分发多少巴斯。我们可以将其表示为sum表达式:
我们可以用这个来计算Bath的 k 的数量,以获得具有 M 的完整行的数量:
如果我们只考虑 * 完整 * 轮,第一个人将拥有 M×(M+1)/2,第二个人拥有 M×(M+1)/2+M,第 j 个人拥有 M×(M+1)/2+j×M。
有可能还有巴斯的剩余,实际上,在 M 轮之后,还有 r = K-M ×n×(m+n)/2 剩余,这些然后在最后一轮中分配。这里,min(M+1,r),第二个 min(M+2,max(r-M-1,0)),第三个 min(M+3,max(r-2×M-3,0)),等等。
如果我们这样假设所有的算术运算都在 O(1) 内运行,那么下面的算法在 O(n) 内运行:
我们可以通过列举可能的浴室来检查结果,例如有四个人: