2012 藍橋杯【初賽試題】大數乘法
大數乘法
對於32位字長的機器,大約超過20億,用int類型就無法表示了,我們可以選擇int64類型,但無論怎樣擴展,固定的整數類型總是有表達的極限!如果對超級大整數進行精確運算呢?一個簡單的辦法是:僅僅使用現有類型,但是把大整數的運算化解為若幹小整數的運算,即所謂:“分塊法”。
如圖【1.jpg】表示了分塊乘法的原理。可以把大數分成多段(此處為2段)小數,然後用小數的多次運算組合表示一個大數。可以根據int的承載能力規定小塊的大小,比如要把int分成2段,則小塊可取10000為上限值。注意,小塊在進行縱向累加後,需要進行進位校正。
以下代碼示意了分塊乘法的原理(乘數、被乘數都分為2段)。
#include <stdio.h>
#include <iostream>
using namespace std;
void bigmul(int x, int y, int r[])
{
int base = 10000;
int x2 = x / base;
int x1 = x % base;
int y2 = y / base;
int y1 = y % base;
int n1 = x1 * y1;
int n2 = x1 * y2;
int n3 = x2 * y1;
int n4 = x2 * y2;
r[3] = n1 % base;
r[2] = n1 / base + n2 % base + n3 % base;
--------------- // 填空
r[0] = n4 / base;
--------------- //填空
r[2] = r[2] % base;
r[0] += r[1] / base;
r[1] = r[1] % base;
}
int main(int argc, char* argv[])
{
int x[] = {0,0,0,0};
bigmul(87654321, 12345678, x);
printf("%d%d%d%d\n", x[0],x[1],x[2],x[3]);
system("pause");
return 0;
}
解題思路:
不算難,就是類似平時乘法運算中的進位
按照它的算法,99*99應該是這個樣子
99*99正常方法:
99
x99
---------
891
891
---------
9801
99*99用題中敘述的方法:
99
x99
---------
81
81
81
81
---------
9 8 0 1
假設9為r[0],8、0、1分別是r[1]、r[2]、r[3],四個81分別是n1,n2、n3、n4。
則r[3]=n1%10;
r[2]=n1/10+n2%10+n3%10;
r[1]=n4%10+n2/10+n3/10;
r[0]=n4/10;
得到了上麵的一組結果,很容易就推出了空格1,空格二就是簡單的進位加減了,嘿嘿,分值到手!
#include <stdio.h> #include <iostream> using namespace std; void bigmul(int x, int y, int r[]) { int base = 10000; int x2 = x / base; int x1 = x % base; int y2 = y / base; int y1 = y % base; int n1 = x1 * y1; int n2 = x1 * y2; int n3 = x2 * y1; int n4 = x2 * y2; r[3] = n1 % base;//取最後一位 r[2] = n1 / base + n2 % base + n3 % base;//取倒數第二位(n1的首和n2、n3的尾相加) r[1] = n2 / base + n3 / base + n4 % base; //取倒數第三位(n2、n3的首與n4的尾相加) r[0] = n4 / base;//取n4的首 r[1] += r[2] / base; // r[1]要加上後麵進位的數 r[2] = r[2] % base;//隻取進位後的餘數 r[0] += r[1] / base;//r[0]要加上後麵進位的數 r[1] = r[1] % base;//隻取進位後的餘數 //r[3]沒有做任何加減,所以不需要進位也不需要加任何一位進的位數 } int main(int argc, char* argv[]) { int x[] = {0,0,0,0}; bigmul(87654321, 12345678, x); printf("%d%d%d%d\n", x[0],x[1],x[2],x[3]); system("pause"); return 0; }
最後更新:2017-04-03 12:55:32