POJ1423 Big Number解题报告

_考查点:

数学思维。

_思路:

这个题用模拟的方法肯定会超时的,因为n!(n可以高达10^7),这个阶乘是一个非常大的数,

就算用高精度来存都很恐怖,最多能达到数量级上限千万位(n为10^7时有65657060位).

既然模拟不行.那么我们就想想数学方法吧。数学总是能带给我们惊喜。既然是求位数

那么就是就这个数以10为底的对数。哎,这么想就对了,既然是求对数那就简单了。

由对数的性质可以知道log10(n!) =  log10(1)  +  log10(2)  + ... + long10(n);这么就可以避免

数据太大造成的麻烦。但是直接这么写了提交还是会超时n能高达10^7...多来几次就TLE了。

那么我们可以事先求出间隔x增量的数的阶乘的对数存放在数组中。比如以一百万为间隔。

这样时间复杂度就降下来了。求一个case最多百万次循环.要更快,也可以以10万为间隔,但是那个

就要存100个数据,我太懒了,就选的100万为间隔的了。

_提交情况:

TLE一次,为事先打表。

_收获:

数学是个好东西啊!!!

_AC CODES:

#include <cstdio>
#include <cmath>

double array[11] = {0, 5565708.917187, 11733474.577126,
                18128483.956099, 24671065.737818, 31323381.360738,
                38063144.399049, 44875628.728418, 51750367.891344,
                58679536.124036, 65657059.080059};

int main() {
    int i, n, m;

    scanf("%d", &n);
    while (n--) {
        scanf("%d", &m);
        for (i = 10; i >= 0; i--) {
            if (m >= i * 1000000) {
                break;
            }
        }
        double sum = array[i];
        for (int j = i * 1000000 + 1; j<= m; j++) {
            sum += log10((double)j);
        }
        int a = (int)sum;
        if (1 == m || sum - a > 0) {//注意log10(1)是为0的.得单独讨论1 == m的情况
            a++;
        }
        printf("%d\n", a);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值