给输入一个正整数n,输出一个列表 连续的正整数,总结起来,将弥补这一点 数字或不可能,如果无法完成。如果有多种可能 anwers,输出任何最少的值。
这是几天前举行的CERC竞赛的一个问题,虽然我可以用一些奇怪的理论来解决它,但我不知道如何优雅地解决它。
我知道2 ^ i形式中没有数字,其中i是非负整数,并且任何奇数都可以以二阶形式的地板(n / 2)+(地板( n / 2)+1)但是当谈到偶数时,我对一些优雅的解决方案一无所知,我听说它可以用一个公式来解决。我考虑将数字除去,直到我们留下奇怪的东西,然后试图将这个奇数的加数放在偶数的中心,或者试图将数字除以中间的奇数但是它没有听起来不对,更不用说优雅了。有些团队在10分钟内解决了这个问题,所以我上面提到的路线几乎肯定是错的,而且我太过于思考它了。
解决这个问题的最佳和最快方法是什么?
答案 0 :(得分:2)
m
到n
的一组正整数之和为
n(n + 1)/2 - m(m - 1)/2
(即从1
到n
的数字总和减去从1
到m - 1
的总和
((n^2 - m^2) +(n + m))/2
是
(n + m)( n - m + 1)/2
因此,如果您需要为某些x
制作相等的x2x = (n + m)(n - m + 1)
所以寻找2x的因子,看看哪种模式适合
答案 1 :(得分:0)
Ookay,因为@ Pokechu22对我的团队如何解决它感兴趣(似乎甚至还有一个人,从消息旁边的upvote判断:)),这里就是这样。它有效,它符合时间限制,但要注意它有点扭曲,即使在这几天之后我仍然怀疑它是否仍然记得它是如何工作的:D让我们开始吧。
首先,我们if
两个场景 - 如果n为1,则输出Impossible
,如果n为奇数,则输出floor(n/2)+(floor(n/2)+1)
。现在真正有趣:
我们知道任何偶数必须是至少三个连续整数的和,因为它是两个的和,我们需要两个连续的奇数或两个连续偶数,这是不可能的。因此,我们以下列形式推导出一系列序列及其相应的总和:
Length | Sequence | Sum
3 1-2-3 6
4 0-1-2-3 6
5 0-1-2-3-4 10
6 IMPOSSIBLE N/A
7 1-2-3-4-5-6-7 28
8 0-1-2-3-4-5-6-7 28
9 0-1-2-3-4-5-6-7-8 36
10 IMPOSSIBLE N/A
......等等
事实证明,每个可能的答案序列只是其中之一,向右移动了一些数字。要查找数字是多少,对于上表中的每个元素sum_i
,我们会检查n-sum_i
是否可以被length_i
整除。如果是,我们有我们的解决方案,因为剩下的就是将给定序列移动那么多位置(换句话说,将(n-sum_i)/length_i
添加到sequence_i
的每个元素)。如果在开头使用带有0的序列,我们还必须记住将其向右移动一个额外的空格(从下一个整数开始)。因此,我们得到一个代码如下:
bool shouldBeShifted = false;
bool foundSolution = false;
long long sum_i = 6, length_i = 3;
while(n - sum_i >= 0)
{
long long tmp = n - sum_i;
if(tmp % length_i == 0) {foundSolution = true; break;}
++length_i;
if(tmp % length_i == 0) {foundSolution = true; shouldBeShifted = true; break;}
sum_i += length_i;
++length_i;
tmp = n - sum_i;
if(tmp % length_i == 0) {foundSolution = true; break;}
length_i += 2;
sum_i = ((3 * length_i) - 3) + sum_i;
shouldBeShifted = false;
}
如果循环foundSolution
结果为true
后,我们找到了一个长度为length_i
的解决方案,从(n / length_i) - (length_i / 2) + (shouldBeShifted ? 1 : 0)
开始:)信不信由你,它确实有效并找到最佳解决方案......:D