我正在尝试编码Finding the position at n?中引用的问题。为此,我只使用了问题中公布的公式。我没有通过公式和答案他们对我来说有点太复杂了。我在python中编写了代码,它在这里表示。
这种舞蹈要求每个表演者遵循一系列精确的步骤:
•第0阶段:首先,通过在0号位置设置起点来远离障碍物
•第1阶段:向前迈出一步(+1步)
•第2阶段:向后退两步(-2步)
•要遵循,通过特定的计算,每次都可以获得下一步所需的步骤和方向:您在前一阶段所采取的步数减去您的步数倒数第二阶段。
也就是说,在第3阶段,舞者必须向后退步3步(-2 - 1)。
在第3阶段,舞者处于-4位置。
阶段(n)=阶段(n-1) - 阶段(n-2)
pos(n)= pos(n-1)+ stage(n)
在第4阶段,舞者处于-5位置。
#!/usr/bin/python
if __name__=="__main__":
s = [0, 1, -2]
p = [0, 1, -1]
for n in range(3, 5):
diff = s[n - 1] - s[n - 2]
s.append(diff)
p.append(p[n - 1] + diff)
print "Position at stage %s is %s" %(n, p[len(p) - 1])
我的问题是假设我们有超过1000万个阶段。列表p和s将增长并可能导致内存问题。有没有办法解决这个问题。我找不到另一个解决方案,而不是使用列表。
如果删除第一个元素s.pop() p.pop()
,则它是一个超出范围异常的索引。这是正常的。除此之外,我无法确定在哪里继续。
我想的更简单。
#!/usr/bin/python
if __name__=="__main__":
last_move = -2
penultimate_move = 1
previous_position = -1
for n in range(3, 5):
#compute current move and position
current_move = last_move - penultimate_move
current_position = previous_position + current_move
#do switch in here
penultimate_move = last_move
last_move = current_move
previous_position = current_position
print "current position %s" %current_position
答案 0 :(得分:7)
对此有一个简单的解决方案:在阶段6,7和8,位置分别为0,1和-1,这些位置与初始位置相同。由于下一阶段和位置仅取决于前一对阶段和先前的位置,因此保证重复相同的序列。
所以计算给定 n 的位置的函数可以是:
def position(n):
return [0, 1, -1, -4, -5, -3][n % 6]
用数字 n 计算阶段的函数:
def stage(n):
return [3, 1, -2, -3, -1, 2][n % 6]
答案 1 :(得分:4)
对于这类问题,你必须尝试为某些情况找到解决方案,也许你会找到一个像我找到的模式,它将帮助你在O(1)时间内解决这个问题,只有6个元素的列表。< / p>
让我们迭代几个初始阶段,
Steps to take New position
Stage 0 --- 0
Stage 1 1 1
Stage 2 -2 -1
Stage 3 -3 -4
Stage 4 -1 -5
Stage 5 2 -3
Stage 6 3 0
Stage 7 1 1
Stage 8 -2 -1
Stage 9 -3 -4
Stage 10 -1 -5
所以你可以看到Stage 6
模式重复之后。所以下面的python代码将帮助您更快地解决这个问题。
def getpos(n):
'''Returns the position of the performer after nth stage.'''
ls = [0, 1, -1, -4, -5, -3]
return ls[n % 6]
def getstep(n):
'''Returns the step taken at nth stage'''
ls = [3, 1, -2, -3, -1, 2]
if n == 0:
return None
return ls[n % 6]
函数getpos()
和getstep()
是此问题中您需要的实用函数。
答案 2 :(得分:3)
好;让我们从重复定义开始:
stage(n) = stage(n-1) - stage(n-2)
pos(n) = pos(n-1) + stage(n)
现在,让我们制作三个变量:
pos is for pos(n) -- position
ult is for stage(n-1) -- ultimate
pen is for stage(n-2) -- penultimate
如上所述,更新很简单。 这个初始值在问题和代码中给出:
pos = -1
ult = -2
pen = 1
现在,每次循环,更新上面给出的值。
stage_n = ult - pen
pos += stage_n
最后一步是准备下一次迭代。当我们再迈出一步时,这将成为下一次迭代的终极;目前的终极被降级为倒数第二名:
pen = ult
ult = stage_n
......现在我们已准备好回到循环的顶端。
总的来说,它看起来像这样:
limit = <wherever you want to stop>
pos = -1
ult = -2
pen = 1
for n in range (3, limit):
stage_n = ult - pen
pos += stage_n
pen = ult
ult = stage_n
print "Step", limit, "is at position", pos
答案 3 :(得分:2)
你有1000万+阶段的原因是迫使你学习这个技巧。
有助于以差分方程的形式来看待它,
s(n+1) = s(n) - s(n-1)
p(n+1) = p(n) + s(n+1)
将每个步骤视为2个数组s_n
和p_n
,
s_n = [ s(n), s(n-1) ]
p_n = [ p(n) ]
我们如何找到s_n+1
和p_n+1
?看看公式,
s_n+1 = [ s_n[0] - s_n[1], s_n[0] ]
p_n+1 = [ s_n+1[0] + p_n[0] ]
希望这是有道理的。您只需要指定状态来解决方程,而不是整个历史。我可能会弄错,但我认为它被称为&#34;无记忆&#34;在LTE系统中。基本上你是在计算差分方程(离散动态系统),这在DSP中很常见。我在实时DSP实验室学到了这种技术。 :)
答案 4 :(得分:0)
public int calculate( int iterationNumber )
{
int position = 0;
int step1 = 1;
position = position + step1;
iterationNumber = iterationNumber - 1;
int step2 = -2;
position = position + step2;
iterationNumber -= 1;
while( iterationNumber > 0 )
{
position = position + ( step2 - step1 );
int buffer = step1;
step1 = step2;
step2 = step2 - buffer;
iterationNumber -= 1;
}
return position;
}
@Test
public void positionOfTheDancerTest()
{
assertEquals( -4, positionOfTheDancer.calculate( 3 ) );
assertEquals( -5, positionOfTheDancer.calculate( 100000 ) );
assertEquals( 1, positionOfTheDancer.calculate( 2147483647 ) );
}