Uva - 10106 - 大整数相乘

来源:互联网 发布:北大青鸟网络管理 编辑:程序博客网 时间:2024/05/16 19:13

Uva 10106:

 = = 感觉收拾收拾也能倒腾出一个折腾大整数的专题...

可惜我那个懒啊。

 

题目的大意是两个大整数相乘输出结果。

         大整数 < 10^250 .

         思路基本和大整数相加一样。将字符串转换为阿斯克码。

   

          数学上整数相乘: 123 *12 = 1476 .

                    1     2     3

            x             1     2  

        _____________________

                    2     4     6

              1    2     3

        ______________________

              1    4     7      6         

                                    

就像两个数相加一样  如   9+1 = 10 , 进了一位。

          假设开字符串 char BigNumber[ 260 ] = "9";

          那么 BigNumber [ 0 ] =' 9 ' ,这已经是数组的第一个元素了,如遇进位情况,就没有办法存辣个 ‘ 1 ’ 啦~~

          所以为了解决这种情况,就把字符串倒叙 做一个 reverse(  BigNumber,BigNumber+LenN );

          这样假设你输入的数据是123456789,倒叙之后就是987654321--> 这里还剩下很多位数可以拿来进位。

 

再接下来就要解决两个大整数相乘的问题了:

          10 * 10 = 100 ,结果是三位数,两个零。 = =   所以推出 题目中的大整数相乘的和最大有五百位。

           但是为了保险还是多开一点啦。。

 

               BigNumber_a[ 300 ] = " 123456 ";

               BigNumber_b[ 300 ] = " 22 ";

 

那么倒叙之后:    

                                        数组下标:              0     1     2     3     4     5     6     7.......

                                         a 串( j ):           6     5     4     3     2     1

                                         b串( i ):            2     2   

 

              大整数相乘的字符串下标:

                                                               0     1     2     3     4     5     6     7     8     9     ......

b 串的下标为 0的 ‘ 2 ’与 a 串相乘:      1     3     0     8     6     4     2

再将下标为 1 的‘ 2 ’ 与 a 串相乘 :              1     3     0     8     6     4     2

           

                                        由此就可以找出规律 <_< 算出大整数相乘辣个数组的下标...说不清楚啦~

                                        就是   i+j      <_< 这个。具体自己琢磨。

 

PS:有个坑 阿斯码的范围。一开始WA了百思不得骑姐 T^T~

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAXSIZE = 300;char BigNumber[ MAXSIZE ];char BigSum[ MAXSIZE ];char Sum[ 2*MAXSIZE ];char Zero[]="0";#define REP(i,n) for(int i = 0; i < n; ++i )void DigitSum( int &ln ,int &ls){    int n = ln;    short tinysum = 0;    REP(i,n)        for( int j = 0; j < ls ; ++j )        {                tinysum = ( BigNumber[i] - '0' ) * ( BigSum[j] - '0' );                int indx = i + j;                if( tinysum > 9 )                {                    Sum[indx] += (  tinysum%10 );                    Sum[indx+1] += ( tinysum/10 );                }                else Sum[ indx ] += tinysum;                if( Sum[indx]>'9' )                {                    Sum[indx] -= 10;                    Sum[indx+1] +=1;                }        }// end of ls}/*void SortSum( ){    int n = 2*MAXSIZE ;    REP(i,n)        if( Sum[i]>'9' )        {            Sum[i] -= 10;            Sum[i+1] +=1;        }}  一开始在所有的数乘完之后做这一步 = = 后来 WA了    测试一下 444444444444444444444444 * 4444444444444444444444444444  我才豁然顿悟 可能会加到超出字符类型的范围 必须 单个数位乘完就立马做这一步  不然会wa的很有节奏!!!*/void OutPut(){        int i;        for(  i = 0; i < 2*MAXSIZE ;++i)                    if( Sum[i]!= '0')break;        while( i< 2*MAXSIZE )        {           putchar(Sum[i++]);        }        printf("\n");}int main(){    while( gets(BigNumber) )    {        gets(BigSum);        if( ( strcmp(BigNumber,Zero)==0 ) || (strcmp(BigSum,Zero)==0) )puts("0");        else        {            memset(Sum,'0',sizeof(Sum));            int LenN = strlen(BigNumber);            int LenS = strlen(BigSum);            reverse(  BigNumber,BigNumber+LenN );            reverse(  BigSum,BigSum+LenS   );            DigitSum(LenN,LenS);            //SortSum();            reverse(Sum,Sum+(2*MAXSIZE));            OutPut();        }    }    return 0;}


 

 

 

 

 

        

 

 

 

0 0