蓝桥杯 ADV-206 算法提高 不大的数

问题描述

  在当今的大数据时代,超大数的高精度计算已经成为众多领域的热门研究之一。现在T校也想在此领域有所造诣已造福于全社会,然而由于时间有限,所以短时间内难以找出大数计算的通用算法,于是学校找到了同学中的“神霸”——你来帮忙,并仅要求你能在数并不算大的时候给出结果。又出于某种特殊需要,也并不要求你给出数的全部结果,而只是要求结果的前10位(注意不是后10位),并考虑到2的幂次的特殊性和典型性,所以要你计算的数均为2的幂次。

输入格式

  一个自然数n。

输出格式

  2的n次幂的前10位。

样例1 输入

  60

样例1 输出

  1152921504

样例2 输入

  60000

样例2 输出

  6305794870

数据规模和约定

  0<=n<=10000000

注释

  =。=

 

分析:本来想用位运算。。后来发现做不出来。。然后换了种方法做,AC了~

1.当乘以2的次数超过或者等于34次的时候,就会超过10位数字。用一个double型变量保存要求的数,然后再最后转为long long int 型。(至于为什么要用double型,因为第二步的除以1000相当于乘以1024,为了避免失去精度使得除法运算后的结果被转为int后不精准~~)为了防止超过10位数字,这个时候可以采取除法的方式让它位数控制在double的不溢出范围之内~~

2.已知2的10次方是1024,也就是说对于每一个是10的倍数i,就相当于给要求的数增加了1024倍,这个时候可以采取除以1000的方式保证它不溢出~

3.但是因为数据规模太大了,有一千万大小,所以每一个1024/1000=1.024,当乘以1.024的个数超过97次方的时候(1.024^97 = 9.979201547674),就会等于让要求的数乘以了10.为了保证不溢出,可以在乘以了每970个2的时候,让要求的数除以10保证不会溢出~(如果想要更精准的可以用计算器得到:1.024^97.1 = 10.00289683498)就是每乘以971个2后除以10~
4.此时用上述办法得到的数如果在数据规模大的时候可能会有10位或者11位,这时候可以统计一下这个double型数字的位数,然后进行除以10的运算把它变为前面只有10位数。

5.此时转换为long long int型输出即可~

#include 
using namespace std;
int main() {
    int n;
    cin >> n;
    double t = 1.0;
    for(int i = 1; i <= n; i++) {
        t = t * 2;
        if(i >= 34 && i % 10 == 0) t = t / 1000;
        if(i % 971 == 0) t = t / 10;
    }
    long long int temp = t;
    int sum = 0;
    while(temp) {
        temp = temp / 10;
        sum++;
    }
    while(sum > 10) {
        t = t / 10;
        sum--;
    }
    long long int d = t;
    printf("%lld", d);
    return 0;
}

 

你可能感兴趣的:(蓝桥杯,蓝桥杯)