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.

posted @ 2010-03-29 09:30  jesonpeng  阅读(358)  评论(0编辑  收藏  举报