题意大概是给一组数M,N,求出第M个末位有N个0的Fibonacci数列是第几项。
乍一看,吓我一跳,结果在2^31内,大的惊人。后来拿一个程序(正好是TOJ的一道题,求1000位内的Fibonacci数列)暴力了下,好家伙,有规律的。
第一个末位有1个0的是第15项,第二项第30…然后看末位有2个0的,第一个是150项,第二个第300项。然后很高兴了写了个程序,WA...
有点晕,又暴力了下,加大范围,发现第一个末位3个0的不是1500项,而是750项。无奈了,好奇怪。于是猜只有这一个特例,依然WA。最后请教了个
学长,他说他也是猜的,不过后边的确实都是10倍了,就那一个特例。
接下来其实过程异常艰辛,不过最终思路很清晰,也AC了。
--------------------------------------------------------我是低调的分割线-------------------------------------------------------------------------------------
大概是这样分布的:
15 30 45 ... 150 165 180 195 ... 300 ... 750 ... 1500 ... 7500
第1个0 第2个0 第3个0 第1个00 第10个0 第11个0 第12个0 第2个00 第1个000 第1个0000
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
所以可以看到,不能直接按间隔算,因为比如150.,它算2个0,而不是第10个1个0。
又不能枚举,一定会超时(确实超了)
所以可以先按照没有重叠算,然后加上重叠的,重叠的只算下一个就好,因为再后边的也就都包括了。
算重叠的部分要把特殊的2拿出来。倍数是5就是 4 1 4 1 4 1这样分布,10的话就是 9 1 9 1 9 1 9 1 9 1,所以按照这样算,
比如要求第14个末位有2个0的,14%4!=0 ,14/4=3,所以重叠了3次。又比如20, 20%4==0,20/4-1=4,重叠4次。
Code:
1 #include<stdio.h>
2 int main(void)
3 {
4 int a[18]={0,15,150,750,7500,75000,750000,7500000,75000000,750000000}; //保存第一个连续1个0,2个0的第一个
5 int i,j,k,m,n,cas,key;
6 scanf("%d",&cas);
7 while(cas--){
8 scanf("%d%d",&n,&m);
9 key=m*a[n];
10 if(n==2){
11 if(m%4!=0) key+=(m/4)*a[n];
12 else key+=(m/4-1)*a[n];
13 }
14 else{
15 if(m%9!=0) key+=(m/9)*a[n];
16 else key+=(m/9-1)*a[n];
17 }
18 printf("%d\n",key);
19 }
20 }