题目链接:
题意:
定义斐波那契数列:F[1]=1,F[2]=1,F[n]=F[n-1]+F[n-2] (n>=3) 。给定一个 w , ,要求在 F[F[x]] 中找任意个数,其和等于 w ,输出其 x 。若有多组解,输出字典序最小的。若不存在,输出 -1 。
思路:
设 ff[x] = F[F[x]]。斐波那契数列增长速度接近 ,因此 ff[x] 增速接近 。用 py 打表可知,在 的范围中,有29个ff[x](即 ff[30] > )。
如何打表:
由于范围内斐波那契数列有 项,不能将其存入一个数组中(大数是字符串,空间会爆)。因此可以用矩阵快速幂计算斐波那契数列,,其中 n>=2 。然后直接对 ff[x] 打表即可。
由于 ff[x] 中各项跨度很大,经计算可以发现只有 <=5 的数有多种组合方式。而且 ff[x] 只有29项,因此我们直接从 ff[x] 最后一项开始遍历,若 w>ff[i],w-=ff[i],并把该 ff[i] 记入答案,遍历到5即可停止,最后5项特判即可。
tips:py range区间左闭右开 。
Code:(py 2.7)
def Mul(a,b):
c = [[0,0],[0,0]]
c[0][0]=a[0][0]*b[0][0]+a[0][1]*b[1][0]
c[0][1]=a[0][0]*b[0][1]+a[0][1]*b[1][1]
c[1][0]=a[1][0]*b[0][0]+a[1][1]*b[1][0]
c[1][1]=a[1][0]*b[0][1]+a[1][1]*b[1][1]
return c
def fastm(a,num):
res=[[1,0],[0,1]]
while num>0:
if num%2==1:
res = Mul(res,a)
num=num/2
a=Mul(a,a)
x=res[0][0]+res[1][0]
return x
f=[[1,1],[1,0]]
ff=[0,1,1,1,2,5]
for i in range(6,30):
x = fastm(f,i-2)
ff.append(fastm(f,x-2))
t = int(input())
while t>0:
t=t-1
ans=[]
w = int(input())
for i in range(29,0,-1):
if i<=5:
break
if w>=ff[i]:
w=w-ff[i]
ans.append(i)
if w>5:
ans.append(5)
w=w-5
if w>5:
print(-1)
continue
if w==5:
ans=ans+[4,3,2,1]
elif w==4:
ans=ans+[4,2,1]
elif w==3:
ans=ans+[3,2,1]
elif w==2:
ans=ans+[2,1]
elif w==1:
ans.append(1)
for i in ans[:0:-1]:
print(i),
print ans[0]