hdc1568
(f[0]=0,f[1]=1;f[i] = f[i-1]+f[i-2](i>=2))的值全部给背了下来。
接下来,CodeStar决定要考考他,于是每问他一个数字,他就要把答案说出来,不过有的数字太长了。所以规定超过4位的只要说出前4位就可以了,可是CodeStar自己又记不住。于是他决定编写一个程序来测验zouyu说的是否正确。
对数log()的作用,先让我们回忆一下log 的运算性质吧~
1)log(a*b)=log(a)+log(b); 2)log(a/b)=log(a)-log(b);
其实在数学里面,log可以求一个大数的科学计数法的数值部分,比如说123456
首先log10(1234567)=log10(1.234567*10^6)=log10(1.234567)+6; 然后log10(1.234567)就是log10(1234567)的小数位
然后10^log10(1.234567)=1.234567,所以通过这样的转换 我们可以很巧妙的得到了一个很大的数的科学计数法的表示值!
然后您要取4位就拿4位!要多少位就拿多少位!
取10的对数为:
log10(an)=-0.5*log10(5.0)+((double)n)*log(f)/log(10.0)+log10(1-((1-√5)/(1+√5))^n)
其中f=(sqrt(5.0)+1.0)/2.0;
log10(1-((1-√5)/(1+√5))^n)->0 趋近于0
所以可以写成log10(an)=-0.5*log10(5.0)+((double)n)*log(f)/log(10.0); 为什么是log(10.0) 运用了对数的性质。
最后取其小数部分。对于10^X,X为一个实数,可以分解为一个整数和一个小数的和,X=Z+P,即10^X=10^(Z+P)
=10^Z * 10^P,(0<=P<1).显然10^Z不会影响到10^X的数字。最后只要取10^P的前四位数。
代码如下:
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; int f[21] = {0, 1, 1}; int main() { int n; for(int i = 2; i < 21; ++i) f[i] = f[i - 1] + f[i - 2]; while(scanf("%d", &n) != EOF) { if(n <= 20)//区别与其他多于四位的答案,20是6765,21时 10946 { printf("%d\n", f[n]); continue; } else { double temp = -0.5 * log(5.0) / log(10.0) + ((double)n) * log((sqrt(5.0)+1.0)/2.0) / log(10.0); temp -= floor(temp); temp = pow(10.0, temp); while(temp < 1000) temp *= 10; printf("%d\n", (int)temp); } } return 0; }
令一版本:
#include<iostream> #include<cstdio> #include<cmath> using namespace std; int s[21]={0,1,1,2}; const double f=((double)sqrt(5.0)+1)/2.0; void get_Fibonacci(int x){ if(x<=20) printf("%d\n",s[x]); else{ double ans=(-0.5)*log(5.0)/log(10.0)+(double(x))*log(f)/log(10.0); ans=ans-floor(ans); double k=pow(10.0,ans); //cout<<"k= "<<k<<endl; while(k<1000.0) k*=10.0; printf("%d\n",(int)k); } } int main(){ int x,i; for(i=3;i<=20;i++) s[i]=s[i-1]+s[i-2]; //在这里为了区别其他多于4位的答案我先把4位以内的 //都计算好存起来! while(~scanf("%d",&x)){ //为什么加~,不加可不可以?-1 补码11111111,取反后为0,退出,不能为!,eof为-1;还是没退出 if(x==0){ printf("0\n"); continue; } get_Fibonacci(x); } return 0; }
c++ log double log ( double x );
float log ( float x );
long double log( long double x );
Compute natural logarithm Returns the natural logarithm of x. (以e为底
double log10 ( double x );
float log10 ( float x );
long double log10 ( long double x );
Compute common logarithm Returns the common (base-10) logarithm of x.
scanf的返回值问题:
msdn解释:Both scanf and wscanf return the number of fields successfully converted and assigned; the return value does not include fields that were read but not assigned. A return value of 0 indicates that no fields were assigned.
The return value is EOF for an error or if the end-of-file character or the end-of-string character is nocountered in the first attempt to read a character.
scanf()函数返回成功赋值的数据项数,读到文件末尾出错时则返回EOF。
scanf()函数返回成功赋值的数据项数,读到文件末尾出错时则返回EOF。
如:
scanf("%d,%d", &a, &b);
如果a和b都被成功读入,那么scanf的返回值就是2
如果只有a被成功读入,返回值为1
如果a和b都未被成功读入,返回值为0
如果遇到错误或遇到end of file,返回值为EOF。
且返回值为int型.
例:使用scanf函数输入数据。
#include<stdio.h>
int main()
{
int a,b,c;
printf("输入 a, b, c\n");
scanf("%d,%d,%d", &a, &b, &c);
printf("a = %d b = %d c = %d\n", a, b, c);
fflush(stdin);
return 0;
}
注意上面的scanf("%d,%d,%d",&a,&b,&c);中%d,%d,%d之间有逗号,在输入数据时也要加逗号(如果不加除了第一个数正确外,其余都错)如果去掉逗号,输入时就不用逗号,而用空格,tab键或回车键将各个数据隔开
其实scanf()的返回值对我们来说也很有用的,比如我们在使用这个函数进行接收值时,我们很必要知道对要给赋值的变量是否正确的赋值成功了,所以可以使用if(scanf("%d,%d",&a,&b)==2)这样语句来判断是否正确的给所有的变量赋值了,正确的话才能使用这个变量参与运算,这样才能提高我们代码的安全性,所以这个返回值也是大有用途的