• TZOJ 4839 麦森数(模拟快速幂)


    描述

    形如2^P-1的素数称为麦森数,这时P一定也是个素数。但反过来不一定,即如果P是个素数,2^P-1不一定也是素数。到1998年底,人们已找到了37个麦森数。最大的一个是P=3021377,它有909526位。麦森数有许多重要应用,它与完全数密切相关。

    任务:从文件中输入P(1000<P<3100000),计算2^P-1的位数和最后500位数字(用十进制高精度数表示)

    输入

    文件中只包含一个整数P(1000<P<3100000)

    输出

    第一行:十进制高精度数2^P-1的位数。

    第2-11行:十进制高精度数2^P-1的最后500位数字。(一行输出,不足500位时高位补0)

    不必验证2^P-1与P是否为素数。

    样例输入

    1279

    样例输出

    386
    00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010407932194664399081925240327364085538615262247266704805319112350403608059673360298012239441732324184842421613954281007791383566248323464908139906605677320762924129509389220345773183349661583550472959420547689811211693677147548478866962501384438260291732348885311160828538416585028255604666224831890918801847068222203140521026698435488732958028878050869736186900714720710555703168729087

    题意

    先输出十进制高精度数2^P-1的位数再输出最后500位

    题解

    这里求位数我推了好久,其实求位数有个公式:log10(a)*p+1,表示a^p的位数

    这里-1不影响总位数,因为2的倍数末尾只可能是2,4,6,8

    算500位采用快速幂的思想:2^5==(2^2)^2*2  其中2^2==(2^1)^2

    然后模拟一下乘2和平方即可,注意算平方的时候不能越界

    代码

     1 #include<stdio.h>
     2 #include<math.h>
     3 #include<string.h>
     4 int a[505];
     5 void digui(int x){//快速幂思想 
     6     if(x/2!=1) 
     7         digui(x/2);
     8     pifang();
     9     if(x%2==1) 
    10         cheng();
    11 }
    12 void cheng(){//乘2 
    13     int i;
    14     for(i=500;i>=1;i--)
    15         a[i]*=2;
    16     for(i=500;i>=1;i--){
    17         if(a[i]>=10){
    18             a[i-1]+=a[i]/10;
    19             a[i]%=10;    
    20         }
    21     }
    22 }
    23 void pifang(){//平方 
    24     int i,j,p[505];
    25     memset(p,0,sizeof(p));
    26     for(i=500;i>=1;i--)
    27         for(j=500;j>=1;j--)
    28             if(i+j-500>=1)//注意这里不能越界 
    29                 p[i+j-500]+=a[i]*a[j];
    30     for(i=500;i>=1;i--){
    31         if(p[i]>=10){
    32             p[i-1]+=p[i]/10;
    33             p[i]%=10;
    34         }
    35     }
    36     for(i=1;i<=500;i++)
    37     a[i]=p[i];
    38 }
    39 
    40 int main(){
    41     int i,p;
    42     memset(a,0,sizeof(a));
    43     scanf("%d",&p);
    44     printf("%d
    ",(int)(p*log10(2))+1);//直接套公式 
    45     a[500]=2;
    46     digui(p);
    47     a[500]--;
    48     for(i=1;i<=500;i++)
    49         printf("%d",a[i]);
    50     puts("");
    51     return 0;
    52 }
  • 相关阅读:
    java 的 CopyOnWriteArrayList类
    AtomicInteger类的简单应用
    关于java的关键字 transient
    关于ArrayList的一些源码分析
    Eclipse新建java类的时候,自动创建注释
    关于spring-data-jpa的排序问题
    hibernate CascadeType属性
    springBoot框架不同环境读取不同的配置文件
    你迷茫的原因在于读书太少而想的太多!!!
    学历是铜牌,能力是银牌,人脉是金牌,思维是王牌
  • 原文地址:https://www.cnblogs.com/taozi1115402474/p/8371574.html
Copyright © 2020-2023  润新知