Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 谷歌代码堵塞2008:第1A轮问题3_Algorithm - Fatal编程技术网

Algorithm 谷歌代码堵塞2008:第1A轮问题3

Algorithm 谷歌代码堵塞2008:第1A轮问题3,algorithm,Algorithm,在谷歌代码堵塞2008年第1A轮中: 计算前三位数字 数字的小数点 (3+sqrt(5))^n n可以是最大1000000的大数字。 例如:如果n=2,那么(3+sqrt(5))^2=27.4164079。。。答案是027。 对于n=3:(3+sqrt(5))^3=3935.73982。。。答案是935 解决方案之一是创建矩阵M 2x2:[[0,1],-4,6]],然后计算矩阵p=M^n,其中计算由模1000执行。 结果是(6*P[0,0]+28*P[0,1]-1)mod 1000 谁能给我解释

在谷歌代码堵塞2008年第1A轮中:

计算前三位数字 数字的小数点 (3+sqrt(5))^n

n可以是最大1000000的大数字。
例如:如果n=2,那么(3+sqrt(5))^2=27.4164079。。。答案是027。
对于n=3:(3+sqrt(5))^3=3935.73982。。。答案是935

解决方案之一是创建矩阵M 2x2:[[0,1],-4,6]],然后计算矩阵p=M^n,其中计算由模1000执行。 结果是
(6*P[0,0]+28*P[0,1]-1)
mod 1000


谁能给我解释这个解决方案?

我不知道如何解释,但问题的作者已经撰写了。

我将提出一种解决这个问题的方法,甚至不理解解决方案

假设您熟悉斐波那契数:

ghci> let fib = 0 : 1 : zipWith (+) fib (tail fib)
ghci> take 16 fib
[0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610]
并熟悉其闭式表达式:

ghci> let calcFib i = round (((1 + sqrt 5) / 2) ^ i / sqrt 5)
ghci> map calcFib [0..15]
[0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610]
你会注意到((1+sqrt 5)/2)n和(3+sqrt 5)n的相似性

从这里我们可以猜测,可能有一个类似于斐波那契的数列来计算这个

但是什么系列?因此,您计算前几个项目:

ghci> let calcThing i = floor ((3 + sqrt 5) ^ i)
ghci> map calcThing [0..5]
[1,5,27,143,751,3935]
猜测公式的形式为:

thingn=a*thingn-1+b*thingn-2

我们有:

27=a*5+b*1

143=a*27+b*5

我们求解线性方程组,得到:

thingn=4*thingn-1+7*thingn-2(a=4,b=7)

我们检查:

ghci> let thing = 1 : 5 : zipWith (+) (map (* 4) (tail thing)) (map (* 7) thing)
ghci> take 10 thing
[1,5,27,143,761,4045,21507,114343,607921,3232085]
ghci> map calcThing [0..9]
[1,5,27,143,751,3935,20607,107903,564991,2958335]
然后我们发现遗憾的是,这并没有计算我们的函数。但后来我们为它得到了最正确的数字而欢呼。我们不明白为什么,但受到这一事实的鼓舞,我们试图做一些类似的事情。要查找修改公式的参数,请执行以下操作:

thingn=a*thingn-1+b*thingn-2+c

然后我们得出:

thingn=6*thingn-1-4*thingn-2+1

我们检查它:

ghci> let thing =
        1 : 5 : map (+1) (zipWith (+)
          (map (*6) (tail thing))
          (map (* negate 4) thing))
ghci> take 16 thing == map calcThing [0..15]
True

只想回答一个非常古老的问题:

多亏了你,我有了重读维基百科页面上的证明的想法。虽然不是很清楚,但我们可以用它

我们在wikipedia页面上看到一个带有“取整计算”的封闭形式:Fn=⌊φ/√5.⌋N 如果我们能换个新的/√五加三√5(称后者为x)。我们可以相当容易地计算xn的底,特别是mod 1000,通过在我们新构造的序列中找到第n项(这是F的类比子(稍后我们称之为类比子U))

我们要找的序列是什么?好吧,我们试着按照比奈公式的证明来做。我们需要一个以x为根的二次方程。假设x2=6x-4这个有根x和y:=3-√5.现在方便的部分是:

定义Un(针对每个a和b),如下所示:

Un=a xn+b yn

根据x和y的定义,你可以看到

Un=6 Un-1-4 Un-2

现在我们可以自由选择a和b。我们需要Un是整数,所以我建议选择a=b=1。现在是U0=2,U1=6,U2=28

我们仍然需要进行“四舍五入计算”。可以看到,对于每n,yn<1(因为y≅ 0.76<1)so Un=xn+yn=⌈xn⌉.

如果我们能计算Un,我们就能找到⌊xn⌋, 只要减去1

我们可以通过它的递归公式计算Un,但这需要O(n)计算时间。我们可以做得更好

为了计算这种递归公式,我们可以使用矩阵:

⌈ 0 1⌉ ⌈ U(n-1) ⌉     ⌈ U(n) ⌉
⌊-4 6⌋ ⌊  U(n)  ⌋  =  ⌊U(n+1)⌋
称这个矩阵为M。现在M*(U(1),U(2))计算(U(2),U(3))。 现在我们可以计算P=Mn-1(注意,我使用的是小于n的一个,如果你测试小情况,你可以看到这是正确的:n=0,n=1,n=2)P*(6,28)现在给出了序列的第n项和第(n+1)项,所以:

(p*(6,28))0-1=⌊xn⌋


现在我们可以把所有的东西都改为mod 1000(这简化了计算(很多)),我们在计算时间O(log(n))(或者更好地利用矩阵幂的计算奇迹(在循环有限域上))。我想这就解释了这个看起来很奇怪的解决方案。

如果你证明自己至少尝试过某种解决方案,你会发现这个网站上的用户会更愿意提供帮助……我们不是来为你编写代码的(尤其不是为你解决代码阻塞问题)。对于编程竞赛问题的一般帮助,你可以i)阅读官方的竞赛分析(如果有),ii)使用竞赛/裁判自己的论坛询问问题。我不是说你不应该在SO发帖,而是说你更有可能在那里很快得到一个有意义的答案。这一问题在官方的谷歌集团中尤其引起了数页的讨论。