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

来源:互联网 发布:js向上取整函数 编辑:程序博客网 时间:2024/04/29 02:56
问题描述
  在当今的大数据时代,超大数的高精度计算已经成为众多领域的热门研究之一。现在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 <iostream>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;}

2 0