zoukankan      html  css  js  c++  java
  • 【算法学习笔记】35.高精度 竖式乘法 SJTU OJ 1274

    Description

    输入a,b

    输出a*b的竖式乘法,格式见样例。

    Sample Input1

    11
    9
    

    Sample Output1

    11
     9
    --
    99
    

    Sample Input2

    10
    10
    

    Sample Output2

        10
        10
       ---
       100
    

    Sample Input3

    101
    101
    

    Sample Output3

            101
            101
          -----
            101
          101
          -----
          10201
    

    Sample Input4

    10086
    2
    

    Sample Output4

            2
        10086
        -----
           12
          16
        2
        -----
        20172
    

    Sample Input5

    12340012384
    12039847102934
    

    Sample Output5

                  12340012384
               12039847102934
     ------------------------
                  49360049536
                 37020037152
               111060111456
               24680024768
             12340012384
            86380086688
           49360049536
          98720099072
        111060111456
       37020037152
      24680024768
     12340012384
     ------------------------
     148571862351672082734656


    此题虽然没什么算法难度,但是给人的一个启发就是要把样例研究透彻,比如这些案例里隐含了几个条件。
    1.如果一个数为1位数,另外一个数的位数>=3则,把短的放在上面,如果是2或1 则不必处理
    2.如果结果中只有一行则直接输出
    3.如果结果中的某一行全是0则不输出

    代码如下
    #include <iostream>
    #include <cstring>
    
    using namespace std;
    
    
    char a_input[120]={0};
    char b_input[120]={0};
    char res[120][120]={0};//存储每次乘法的计算结果
    int final_res[300]={0};
    inline void printBlank(int n,char flag = ' '){
        for (int i = 0; i < n; ++i)
        {
            cout<<flag;
        }
        return;
    }
    
    void cal(char a[],char b[],int a_len,int b_len){
        int final_res_len = 0;
        for (int i = b_len-1; i >=0; --i)//b[i]是下边的一位数
        {
            int remain = 0;//存储要进位的数
            int index = b_len-1 - i;//这次乘法的计算结果存储到res[index]中
            //逆序存储
            int cur = 0;
            for (int j = a_len -1 ; j >=0; --j)
            {
                int tmp_res = (a[j]-'0') * (b[i]-'0') + remain;
                res[index][cur] = (tmp_res) % 10 + '0';
                remain = tmp_res / 10;
                cur++;
            }
            if(remain>0)//最后还要进一位
                res[index][cur] = remain  + '0';
        }
        //计算最终结果
        for (int i = 0; i < b_len; ++i)
        {
            int remain = 0; //要进位的数
            for (int j = 0; j < strlen(res[i]); ++j)//最低的i位保持不变
            {
                //final_res的第j位 和 j-i-1位对齐
                int temp_res = final_res[j+i] + (res[i][j]-'0') +remain;
                final_res[j+i] = temp_res % 10;
                remain = temp_res / 10;
            }
            if(remain>0)//最后还要进位
            {
                final_res[strlen(res[i])+i] = remain;
                if(i==b_len-1)
                    final_res_len = strlen(res[i])+i+1;
            }else{
                if(i==b_len-1)
                    final_res_len = strlen(res[i])+i;
            }
        }
        
        
        printBlank(final_res_len - a_len);    cout<<a<<endl;
        printBlank(final_res_len - b_len);     cout<<b<<endl;
        printBlank(final_res_len,'-');        cout<<endl;
        
        bool toOutput = false; int cot = 0;
        for (int i = 0; i < b_len; ++i) if(b[b_len-1-i]!='0')
            cot++;
        toOutput = cot>1;
        if(toOutput){
            for (int i = 0; i < b_len; ++i) if(b[b_len-1-i]!='0')
            {
                printBlank(final_res_len - strlen(res[i])-i);
                for (int j = strlen(res[i])-1; j>=0 ; --j)
                    cout<<res[i][j];
                cout<<endl;
                //cout<<strlen(res[i])<<":"<<res[i]<<endl;
            }
            printBlank(final_res_len,'-');      cout<<endl;
        }
    
        for (int i = final_res_len-1; i >=0 ; --i)
        {
            cout<<final_res[i];
        }cout<<endl;
    }
    int main(int argc, char const *argv[])
    {
        char a[120]={0};
        char b[120]={0};
        cin>>a_input;
        cin>>b_input;
        int a_len = 0;
        int b_len = 0;
        //去除前置0
        bool began = false;
        for (int i = 0; i < strlen(a_input); ++i) {
            if(!began and a_input[i]!='0')
                began = true;
            if (began)
                a[a_len++] = a_input[i];
        }
        
        began = false;
        for (int i = 0; i < strlen(b_input); ++i) {
            if(!began and b_input[i]!='0')
                began = true;
            if (began)
                b[b_len++] = b_input[i];
        }
        
        //以上是初始化 
        if(a_len>=3 and b_len == 1)
            cal(b,a,b_len,a_len);
        else
            cal(a,b,a_len,b_len);
        return 0;
    }
    
    /*
     
     
                  12340012384
               12039847102934
     ------------------------
                  49360049536
                 37020037152
               111060111456
               24680024768
             12340012384
            86380086688
           49360049536
          98720099072
        111060111456
       37020037152
      24680024768
     12340012384
     ------------------------
     148571862351672082734656
     
     */
    View Code
  • 相关阅读:
    299. Bulls and Cows
    C# 小知识
    C# Excel写入数据及图表
    C# 委托高级应用----线程——创建无阻塞的异步调用(二)
    C# 委托高级应用----线程——创建无阻塞的异步调用(一)
    C#中的GET和SET访问器
    C# 委托与事件详解(三)
    C# 委托与事件详解(二)
    C# 委托详解(一)
    Visual Studio 实用技能
  • 原文地址:https://www.cnblogs.com/yuchenlin/p/sjtu_oj_1274.html
Copyright © 2011-2022 走看看