算法訓練 麥森數
阿新 • • 發佈:2017-12-31
算法 是個 family str string col color 一個 素數 問題描述
形如2P-1的素數稱為麥森數,這時P一定也是個素數。但反過來不一定,即如果P是個素數,2P-1不一定也是素數。到1998年底,人們已找到了37個麥森數。最大的一個是P=3021377,它有909526位。麥森數有許多重要應用,它與完全數密切相關。
任務:從文件中輸入P(1000<P<3100000),計算2P-1的位數和最後500位數字(用十進制高精度數表示) 輸入格式 文件中只包含一個整數P(1000<P<3100000) 輸出格式 第一行:十進制高精度數2P-1的位數。
第2-11行:十進制高精度數2P-1的最後500位數字。(每行輸出50位,共輸出10行,不足500位時高位補0)
不必驗證2P -1與P是否為素數。
解題思路:對於其位數,直接有數學定理為,int(log10(2)*p+1)
解決2的P次方計算方法如下:
1、用數組作為數據結構進行高精度計算
2、用二分快速冪進行計算
代碼如下:
任務:從文件中輸入P(1000<P<3100000),計算2P-1的位數和最後500位數字(用十進制高精度數表示) 輸入格式 文件中只包含一個整數P(1000<P<3100000) 輸出格式 第一行:十進制高精度數2P-1的位數。
第2-11行:十進制高精度數2P-1的最後500位數字。(每行輸出50位,共輸出10行,不足500位時高位補0)
不必驗證2P
1 #include<iostream> 2 #include<cmath> 3 #include<cstring> 4 using namespace std; 5 int a[502]={0},b[502]; 6 void cal(){ 7 int i,j,k;8 memset(b,0,sizeof(b)); 9 for(i=1;i<=500;i++){//對應相乘 10 for(j=1,k=i;j<=500;j++){ 11 b[k]=b[k]+a[i]*a[j]; 12 k++; 13 if(i==501) break;//乘完第五百位就break,題目要求,再多無益。 14 } 15 } 16 for(i=1;i<=500;i++){//處理進位 17 if(b[i]>=10){ 18 b[i+1]+=b[i]/10; 19 b[i]=b[i]%10; 20 } 21 a[i]=b[i];//更新快速冪 22 } 23 } 24 void recur(int p){ 25 if(p==1 || p==0){ 26 a[1]=2; 27 return; 28 } 29 else{ 30 recur(p/2); 31 cal(); 32 if(p%2==1){//奇數再乘以2 33 memset(b,0,sizeof(b)); 34 for(int i=1;i<=500;i++){//對應相乘 35 b[i]+=2*a[i]; 36 } 37 } 38 for(int i=1;i<=500;i++){//處理進位 39 if(b[i]>=10){ 40 b[i+1]+=b[i]/10; 41 b[i]=b[i]%10; 42 } 43 a[i]=b[i];//更新快速冪 44 } 45 } 46 } 47 int main(){ 48 int p; 49 cin>>p; 50 cout<<int(log10(2)*p+1); 51 recur(p); 52 a[1]-=1; 53 for(int i=500; i>0; i--){ 54 if(i%50 == 0){ 55 printf("\n"); 56 } 57 printf("%d", a[i]); 58 59 } 60 return 0; 61 }
算法訓練 麥森數