1. 程式人生 > >ADV-206 不大的數(高精度乘法)

ADV-206 不大的數(高精度乘法)

問題描述   在當今的大資料時代,超大數的高精度計算已經成為眾多領域的熱門研究之一。現在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 例:
# 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;
}