HDU 5167 Fibonacci——BestCoder Round #28(搜索+预处理)

来源:互联网 发布:java web日志模块设计 编辑:程序博客网 时间:2024/06/07 01:13

Fibonacci

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)


Problem Description
Following is the recursive definition of Fibonacci sequence:
Fi=01Fi1+Fi2i = 0i = 1i > 1

Now we need to check whether a number can be expressed as the product of numbers in the Fibonacci sequence.
 

Input
There is a number T shows there are T test cases below. (T100,000)
For each test case , the first line contains a integers n , which means the number need to be checked. 
0n1,000,000,000
 

Output
For each case output "Yes" or "No".
 

Sample Input
3417233
 

Sample Output
YesNoYes
 

Source
BestCoder Round #28
 
/************************************************************************/

附上该题对应的中文题

Fibonacci

 
 Accepts: 40
 
 Submissions: 1024
 Time Limit: 2000/1000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
问题描述
斐波那契数列的递归定义如下:现在我们需要判断一个数是否能表示为斐波那契数列中的数的乘积。
输入描述
有多组数据,第一行为数据组数TTT \leq 100,000T100,000)。对于每组数据有一个整数nn,表示要判断的数字。0 \leq n \leq 1,000,000,0000n1,000,000,000
输出描述
对于每组数据,如果可以输出“Yes”,否则输出"No"。
输入样例
3417233
输出样例
YesNoYes
/****************************************************/

出题人的解题思路:

Fibonacci序列在10^9109范围内只有43个数,则它们的乘积不超过10^9109的数也不会很多,直接搜索即可。
拿到这道题的时候,理所当然的,预处理一下,先把109内的斐波那契数求出来存好,

然后从大到小遍历斐波那契数,能整除的先除尽,直到遍历结束,判断最后的结果是不是1(n=0的情况另外考虑)。

game over ,过程看起来一气呵成,但是恭喜,最后会和我一样收获到一个WA

然后苦思幂想不得其果,感觉与别人用搜索的方法过程其实没什么差别,但是差别就在这里。

或许直到你找到那么一组数据,才会甘心

n=1008

按我们初始想到的方法,1008=144*7,然后因为7不是斐波那契数,所以No,但是,1008偏偏就能表示成斐波那契数的乘积

1008=2*2*2*2*3*21

这回终于知道为什么错了,在我们从大到小找斐波那契因子的时候,一旦能被整除,会先除尽,

这样就导致大的斐波那契数带走了小的斐波那契数的因子,例如144带走了21里的因子3,导致剩下的7不是斐波那契数

所以还是乖乖用搜索吧,当然若是你把其理解成递归能够好懂一点,也无大碍。

#include<stdio.h>#include<string.h>#include<stdlib.h>#include<queue>#include<math.h>#include<vector>#include<map>#include<set>#include<cmath>#include<string>#include<algorithm>#include<iostream>#define exp 1e-10using namespace std;const int N = 50;const int inf = 1000000000;int s[N];bool judge(int n,int k){    if(n==1)        return true;    for(int i=k;i>2;i--)        if(n%s[i]==0&&judge(n/s[i],i))            return true;    return false;}int main(){    int t,i,n;    s[0]=0,s[1]=1;    for(i=2;i<45;i++)        s[i]=s[i-1]+s[i-2];    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        if(!n)            puts("Yes");        else if(judge(n,44))            puts("Yes");        else            puts("No");    }    return 0;}

菜鸟成长记

0 0
原创粉丝点击