M.J的blog

algorithm,ACM-ICPC
随笔 - 39, 文章 - 11, 评论 - 20, 引用 - 0
数据加载中……

TOJ 3428. Fibonacci(Fibonacci数列的一个规律)

题意大概是给一组数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 }

posted on 2010-04-25 22:50 M.J 阅读(1879) 评论(2)  编辑 收藏 引用

评论

# re: TOJ 3428. Fibonacci(Fibonacci数列的一个规律)  回复  更多评论   

原来是这样做。。。学习了
2010-08-01 15:43 | superbear

# re: TOJ 3428. Fibonacci(Fibonacci数列的一个规律)  回复  更多评论   

学习了!
2012-05-05 19:55 | wyl8899

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理