題意大概是給一組數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 }