P1040
【问题描述】
高精度乘法
输入:两行,每行表示一个非负整数(不超过10000位)
输出:两数的乘积。
【输入样例】
99
101
【样例输出】
9999
分析:如果用一般的高精度算法去算的话只能过几个点,因为一般都是200位以内的数相乘,而题目是10000位以内的数的乘积,除了变量不能用字符串,而应该用ansistring以为,还需要压缩高精度,先把数字变成万进制数,然后计算,就可以提供速度的位数。
type bn=array[0..5000] of longint;
var
a,b,c:bn;
sa,sb,st:ansistring;
l,i,tm:longint;
{变成万进制数}
procedure stn(s:ansistring;var num:bn);
begin
{位数不是4的倍数的用0填满}
while length(s) mod 4 <> 0 do insert('0',s,1);
l:=length(s);
for i:=1 to l div 4 do
begin
st:=copy(s,l-i*4+1,4);
val(st,num[i]);
end;
num[0]:=i;
{num[0]中是位数}
end;
{高精度乘法}
procedure multiply(a,b:bn;var c:bn);
var i,j:longint;
begin
for i:=1 to a[0] do
for j:=1 to b[0] do
begin
inc(c[i+j-1],a[i]*b[j]);
{注意现在是div 10000而不是10}
inc(c[i+j],c[i+j-1] div 10000);
c[i+j-1]:=c[i+j-1] mod 10000;
end;
{判断总的位数,是否要多出一位来}
if c[a[0]+b[0]]=0 then c[0]:=a[0]+b[0]-1 else c[0]:=a[0]+b[0];
end;
begin
readln(sa);readln(sb);
stn(sa,a);stn(sb,b);
multiply(a,b,c);
{下面是输出万进制数,不能直接这样输出
for I=c[0] downto 1 do write(c[i]),这样输出的话10000×10000,不是100000000而是100,不能省略掉中间的0
而且必须先把第一位万进制数输出,不然要输出00010000000。最前面的0需要省略掉
}
write(c[c[0]]);
for i:=c[0]-1 downto 1 do
begin
tm:=1000;
while tm<>0 do
begin
write(c[i] div tm);
c[i]:=c[i] mod tm;
tm:=tm div 10;
end;
end;
writeln;
end.