ADV-206 不大的數(高精度乘法)
阿新 • • 發佈:2018-12-31
問題描述
在當今的大資料時代,超大數的高精度計算已經成為眾多領域的熱門研究之一。現在T校也想在此領域有所造詣已造福於全社會,然而由於時間有限,所以短時間內難以找出大數計算的通用演算法,於是學校找到了同學中的“神霸”——你來幫忙,並僅要求你能在數並不算大的時候給出結果。又出於某種特殊需要,也並不要求你給出數的全部結果,而只是要求結果的前10位(注意不是後10位),並考慮到2的冪次的特殊性和典型性,所以要你計算的數均為2的冪次。
輸入格式
一個自然數n。
輸出格式
2的n次冪的前10位。
樣例1 輸入
60
樣例1 輸出
1152921504
樣例2 輸入
60000
樣例2 輸出
6305794870
資料規模和約定
0<=n<=10000000
註釋
=。=
PS:
一、2^i,當i>34時,會超過10位數字,2^40有13位數字
二、B=2^i,當i>34且i%10==0時,B=B/1000,
即2^10==1024;1024/1000=1.024;
1.024^97.1==10.0028968...
B*2^10/1000==B*1.024
(B*1.024)^97.1/10.0028968...=B=^97.1
三、每乘971個2,要/10
例:
PPS: 1.&n 2.ans = ans * 2; 3.ans > 1000000000000000000(18位) 4.%lld
# include <stdio.h> # include <string.h> // 呼叫strlen函式的標頭檔案 int main(void) { char a1[250], b1[250]; // 先定義兩個字元陣列,用於儲存兩個較多位數的乘數 int a[250], b[250], c[500] = {0}; // 再定義三個陣列,前兩個用於接收字元數組裡的數字各個位的數值,最後一個用於儲存最終結果的各個位的數值 int len1, len2, len; // 前兩個分別表示字元陣列a1,b1的實際長度,最後一個表示兩個字元陣列實際長度之和 scanf("%s%s", a1, b1); // 對兩個字元陣列進行賦值 len1 = strlen(a1); // 將字串a1的長度賦給len1,用於陣列的賦值 len2 = strlen(b1); // 將字串b1的長度賦給len2, 用於陣列的賦值 len = len1 + len2; // 將兩字串實際長度之和賦給len for (int i = 0; i < len1; i++) // 用for迴圈,實現字元陣列a1內數字向陣列轉移 a[i] = a1[len1-1-i] - '0'; /* 不過,字元陣列內的數字與陣列內數字順序相反,這與乘法原理有關,根據ASCII,字元陣列內的數字要轉化成實際的數字,就要減去48,因為‘0’的ASCII碼恰好是48,所以將字元陣列元素-‘0’以實現轉化 */ for (int j = 0; j < len2; j++) // 用for迴圈,實現字元陣列b1內數字向陣列轉移 b[j] = b1[len1-1-j] - '0'; for (int i = 0; i < len1; i++) // 接下來這兩個巢狀的for迴圈便是高精度乘法的核心 for (int j = 0; j < len2; j++) { // 此處這短短三步需要結合乘法原理理解,用文字很難表達 c[i+j] += a[i]*b[j]; // 數字的其中一位與另一數字其中一位相乘,先不考慮進位情況 c[i+j+1] += (c[i+j]) / 10; // 除以10的作用便是判斷進多少(注意是c[i+j]) c[i+j] = c[i+j] % 10; // 進位結束以後該數位便只去各位,故將其取餘取餘數(注意是c[i+j]) } // 此處第一、第二個式子用+=,原因可根據乘法原理解釋,第三個式子無需+=,原因是取該位數總值的個位即可 if (c[len-1] == 0) // 此處是判斷輸出的第一個數位是否為0,若為0,忽略該位數,即總長減去1 len--; for (int i = len-1; i >= 0; i--) // 倒著輸出陣列內的數字,得到最終結果 printf("%d", c[i]); return 0; }
PPS: 1.&n 2.ans = ans * 2; 3.ans > 1000000000000000000(18位) 4.%lld
#include
int main(){
int n,i,j;
long long ans = 1;
scanf("%d",&n);
for(i=0;i 1000000000000000000){
ans /= 10;
}
}
while(ans > 10000000000){
ans /= 10;
}
printf("%lld",ans);
return 0;
}