加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

求大数最左边的某几位数

发布时间:2020-12-14 03:06:53 所属栏目:大数据 来源:网络整理
导读:Ⅰ ?http://acm.hdu.edu.cn/showproblem.php?pid=1715 HDOJ里1715 大斐波数。求第N(1=N=1000)位 斐波那契数,这里只要定义一个二位数组a[1010][3000],然后运用大数运算,用打表的方法把1~1010位大数存到二维数组中,然后再调用。(这里有位N最大是1000,所以

?http://acm.hdu.edu.cn/showproblem.php?pid=1715

HDOJ里1715 大斐波数。求第N(1<=N<=1000)位斐波那契数,这里只要定义一个二位数组a[1010][3000],然后运用大数运算,用打表的方法把1~1010位大数存到二维数组中,然后再调用。(这里有位N最大是1000,所以定义二维数组不会超__int64)。下边是自己的代码http://www.voidcn.com/article/p-acextptf-hp.html

http://acm.hdu.edu.cn/showproblem.php?pid=1250

HDOJ里1250 Hat's Fibonacci。求第N位斐波那契数,这里N没有作限制,但限制了长度不超过2005,通过测试,第7100位斐波那契数刚超2005位,定义二维数组a[7100][2008],但提交以后超内存,虽然没有超__int64。然后才改计算法,改为四位一相加,然后存到数组的二维的一个数组名下,这样成功AC。下边是自己的代码http://www.voidcn.com/article/p-cmbzdpdc-hp.html

还有一类题,求第N位斐波那契数的前n位数,或者求一个大数的前n位数。如HDOJ 1568 Fibonacci,HDOJ 1060 Leftmost Digit。因为N会很大(如1568中(0<N<1000000000))或者大数很大,这时做1568时就不能用二维数组了,因为如果用二维数组,第一维已经到了__int64的极限,再加第二位肯定超。


下面说第种情况的算法:

在这之前先看几个函数。函数的头文件均为#include<math.h>.

1.求log10(X),函数原型double log10(double X);

2.求X^Y的值,函数原型double pow(double X,double Y);

3.求√X,函数原型double sqrt(double X);


说的问题是,如何求一个大数(超出__int64范围,不能用__int64存放)的最左边一位或几位数字。

?给定一个大数num,num还可以写成num=x*10^n,这里x为小数且1<x<10。

1.对num=x*10^n两边同时取以10为底的对数,log10(num)=log10(x*10^n)=log10(x)+log10(10^n),进一步化解,log10(num)=log10(x)+n.

如果要求num的第一位数,只要求出x,然后对x取整,即(__int64)x即为所求。(如果要求前几位数,在最后对x取整时稍作调整即可,后面会说)。

2.现在要求x,所以要做适当的变形,1.中log10(num)=log10(x)+n可变为log10(x)=log10(num)-n,再变一下得到

x=10^(log10(num)-n)。

先来看n,由1.可得 log10(num)=log10(x)+n,而num=x*10^n,所以1<x<10,得0<log10(x)<1,所以log10(x)是

log10(num)的小数部分,n是log10(num)的整数部分,所以n=(__int64)log10(num)。

所以2.中x=10^(log10(num)-n)=10(log10(num)-(__int64)log10(num)).然后再对x取整即为num的第一位数,(__int64)x。

当要求num的前m位数时,在最后对x取整数时要先乘10^(m-1),再取整,即(__int64)(x*10^(m-1))


下面是杭电的两个题,还有我自己的代码

HDOJ1060 Leftmost Digit http://acm.hdu.edu.cn/showproblem.php?pid=1060

#include<stdio.h>
#include<math.h>
__int64 N;
int main()
{
	int T;
	double t;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%I64d",&N);
		t=N*log10((double)N);
		//printf("%lf#n",t);
		t-=(__int64)(t);
		//printf("%lf$n",t);
		printf("%I64dn",(__int64)(pow((double)10,t)));
	}
	return 0;
}

HDOJ1568 Fibonacci http://acm.hdu.edu.cn/showproblem.php?pid=1568

这个题需要用到斐波那契数列第n项的通项公式

因为当n>=20时,才会用到通项公式计算,而n>=20时|((1-5^0.5)/2)^n|<1*10^-5,可以忽略,通项公式可以写成an=(((1+5^0.5)/2)^n)/5^0.5。

#include<stdio.h>
#include<math.h>
int main()
{
	int i,a[20];
	for(i=2,a[0]=0,a[1]=1;i<20;i++)
	a[i]=a[i-1]+a[i-2];
	__int64 N;
	double t;
	while(scanf("%I64d",&N)!=EOF)
	{
		if(N<20)
		printf("%dn",a[N]);
		else
		{
			t=N*log10((1+pow((double)5,0.5))*0.5)-log10(pow((double)5,0.5));
			//printf("%lfn",t);
			t-=(__int64)t;
			//printf("%lfn",t);
			printf("%I64dn",t)*1000));
		}
	}
    return 0;
}



??

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读