题目大意:           求fibonacci数列的前面四位,注意f[0] = 0; 解题思路:           凡是要求数的前面几位的,都可以用两边求对数的思想。让我想起了,m = n^n.要求n的前面一位。这个时候用对数, lg(m) = n*lg(n), m = pow(10, n*lg(n)),之后求n*lg(n)的小数部分,因为整数部分为10^P(p代表整数),全都为10000……,而小数部分则为10^B(B代表小数部分),所以要取几位,就去小数那里取即可。          这是网络上摘来的,写得very good:         先看对数的性质,loga(b^c)=c*loga(b),loga(b*c)=loga(b)+loga(c);         假设给出一个数10234432,那么log10(10234432)=log10(1.0234432*10^7)=log10(1.0234432)+7;           log10(1.0234432)就是log10(10234432)的小数部分.           log10(1.0234432)=0.010063744          10^0.010063744=1.023443198          那么要取几位就很明显了吧~          先取对数(对10取),然后得到结果的小数部分bit,pow(10.0,bit)以后如果答案还是<1000那么就一直乘10。          注意偶先处理了0~20项是为了方便处理~            这题要利用到数列的公式:an=(1/√5) * [((1+√5)/2)^n-((1-√5)/2)^n](n=1,2,3.....) 代码:
#include
#include
const double N1 = (1.0+sqrt(5.0))/2.0;
const double N2 = (1.0-sqrt(5.0))/2.0;
using namespace std;
int main(void)
{
	int n;
	int f[21];
	f[0] = 0;
	f[1] = 1;
	f[2] = 1;
	for(int i = 3; i < 21; i++)
		f[i] = f[i-1] + f[i-2];
	while(scanf("%d", &n) == 1)
	{
		if(n <= 20)
		{
			printf("%d\n", f[n]);
			continue;
		}
		double temp1, temp2, ans;
		temp1 = log10(1.0/sqrt(5.0));
		temp2 = (double)n * log10(N1) + log10(1.0 - pow(N2,(double)n));
		ans = temp1 + temp2;
		ans = ans - (int)ans;
		
		ans = pow((double)10, ans);
	//	printf("%lf\n", ans);
	//	printf("%lf\n", ans);
		printf("%d\n", (int)(ans*1000));
	}
	return 0;
}
TLE代码:
//超时
#include
using namespace std;
const int MAX = 10005;
char str[MAX], str1[MAX], str2[MAX];

void add(char a[], char b[], char c[])
{
	memset(c, '0', sizeof(c));
	int len1, len2, len;
	len1 = strlen(a);
	len2 = strlen(b);
	for(int i = len1-1, j = 0; i >= 0; i--, j++)
		c[j] = a[i];
	for(int i = len2-1, j = 0; i >= 0; i--, j++)
		c[j] += b[i] - '0';
	len = len1 >= len2? len1: len2;

	for(int i = 0; i < len; i++)
	{
		if(c[i] > '9')
		{
			c[i] -= 10;
			c[i+1] ++;
		}
	}
	if(c[len] > '0')
		len++;
	c[len] = '\0';
	strrev(c);
	//for(int i = 0; i < len; i++)
	//	printf("%c", c[i]);
	//printf("\n");
}

int main(void)
{
	int n;
	int cas;

	/*strcpy(str1, "132424");
	strcpy(str2, "123424234");
	add(str1, str2, str);*/
	scanf("%d", &cas);
	while(cas--)
	{
		//	scanf("%d", &n);
		
		for(int n = 1; n < 30; n++)
		{
			strcpy(str1, "1");
			strcpy(str2, "1");
			if(n == 1 || n == 2)
			{
				printf("1\n");
				continue;
			}
			for(int i = 3; i <= n; i++)
			{
				memset(str, '0', sizeof(str));
				add(str1, str2, str);
				strcpy(str1, str2);
				strcpy(str2, str);
			}
			printf("%s\n", str);
		}
	}
	return 0;
}
posted on 2012-02-13 11:23  cchun  阅读(159)  评论(0编辑  收藏  举报