標籤:cin ems post 直接 math i++ 數組 進位 奇數
問題描述 形如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、用二分快速冪進行計算代碼如下:
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 }
演算法訓練 麥森數