杭电ACM——1018,Big Number(思维)

数学题,用取对数函数就好。
突破口:
公式:log(i+1)!=log(i+1)+log(i)!;
遍历1~1e7内所有数的阶乘,记录下其对于10的对数log10(i),最终输出的数要+1。

代码如下:

#include<cstdio>
#include<cmath>
using namespace std;
double f[2500001];  //需要注意,不能直接定义1e7的double数组,这样会爆内存,5000000也不行,这样就刚刚好
int main()
{
    int n,k;
    int i;
    double ans,pre=0; //pre记录阶乘的对数
    f[0]=0;
    for(i=2;i<=10000000;i++)
    {
        pre=pre+log10(i);
        if(i%4==0)  //逢4的倍数就存一次
            f[i/4]=pre;
    }
    scanf("%d",&n);
    while(n--)
    {
        scanf("%d",&k);
        if(k%4==0)
            printf("%d\n",(int)f[k/4]+1);
        else
        {
            if(k%4==1)  //分类讨论
            	ans=f[k/4]+log10(k);
			else if(k%4==2)
				ans=f[k/4]+log10(k-1)+log10(k);
			else
				ans=f[k/4]+log10(k-2)+log10(k-1)+log10(k);
			printf("%d\n",(int)ans+1);
        }
    }
    return 0;
 } 

小结:对数函数有些时候可以发挥很大的作用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值