zoukankan      html  css  js  c++  java
  • Codevs高精度入门(减法、加法和乘法)解题报告

    题目:                                               

     

    题目描述 Description

    给出两个正整数AB,计算A-B的值。保证AB的位数不超过500位。 

    输入描述 Input Description

    读入两个用空格隔开的正整数

    输出描述 Output Description

    输出A-B的值

    样例输入 Sample Input

    3 12

    样例输出 Sample Output

    -9

     

    题目分析                                                           

     

    C++整数数据范围:

    char                          -128 ~ +127                                        (1 Byte)
    short                        -32767 ~ + 32768                       (2 Bytes)
    unsigned short          0 ~ 65536                                        (2 Bytes)
    int                              -2147483648 ~ +2147483647        (4 Bytes)
    unsigned int             0 ~ 4294967295                           (4 Bytes)
    long == int
    long long          -9223372036854775808 ~ +9223372036854775807    (8 Bytes)
    double              1.7 x 10^308                                              (8 Bytes)

     

    long long范围最大,能表示19位。Test Case大于20位就会发生溢出的问题,无法计算。

    所以题目的数据可以选择用string来储存。

    如:string str = “123”//123 = 1 x 102 + 2 x 101 + 3 x 100

    指数位    ———— 下标(数的高位与下标高位相反

    系数位    ————

    为了计算方便,将str转换为int[ ](我习惯用vector).然后用下标和值来进行加减法运算,先得到每一位的值,再进行处理(进位、借位)。

    如:

    vector<int> maxv = { 1, 0, 0, 9 }      // 1000

    vector<int> maxv = { 2, 3 }         // 23

    vector<int> sub, add;

    计算后:sub = { 1, 0, -2, 6 };

    add = { 1, 0, 2, 12 };

    处理后 : sub = { 0, 8, 8, 6 }    // 小于0,借位

           add = { 1, 0, 3, 2 }    // 小于0,进位

    输出:注意处理0

     

    减法

    n   计算:统一用大数减小数,如果输入被减数小于减数,交换它们,标记输出为负。按位相减即可,从低位高位皆可。

    n   转换:高位借位-1,本位+10变为正,依次循环。

    加法与减法类似。

    乘法,用两个循环,依次相乘做和,更新每一位的值。

    这个算式是从数值高位开始算的(直接从vector 0开始),当然也可以按普通乘法计算从低位开始。然后再进行进位转换,注意大于100和大于10的进位。

     

     

    /*

    高精度减法法题目:  http://codevs.cn/problem/3115/

    2015.5.5 shaonian.ding

    */

    #include<iostream>

    #include<vector>

    #include<string>

     

    usingnamespace std;

    //string convert to vector<int> function

    void strToInts(string str, vector<int> &v){

        int len = str.size();

        for (int i = 0; i < len; i++)

        {

           int c = str[i] - '0';

           v.push_back(c);

        }

    }

    int main(){

     

        string maxStr, minStr;//被减数,减数string.

        /*test case*/

        //maxStr = "1000";

        //minStr = "10";

     

        /*Input Data*/

        cin >> maxStr>>minStr;

     

        /*code*/

        vector<int> maxv,minv;//max vectormin vector

        bool isPositive = true;//差正负标记,用来最后输出

     

        //如果减数小于被减数,交换位置他们。差标记为负数,isPositive = false;

        if (maxStr.size() <= minStr.size()){

           if (maxStr.size() == minStr.size()){

               for (int i = 0; i < maxStr.size(); i++)

               {

                  if (maxStr[i] < minStr[i]){

                      swap(maxStr, minStr);

                      isPositive = false;

                      break;

                  }

               }

           }

           else{

               swap(maxStr, minStr);

               isPositive = false;

           }

          

        };

     

        //string convert to ints

        strToInts(maxStr, maxv);

        strToInts(minStr, minv);

     

        //maxv = maxv - minv;高位开始减,得到序列max = {1,0,-1,0}

        for (int i = 0; i < minv.size(); i++)

        {

           int j = maxv.size() - minv.size()+i;

           if (i<minv.size()){

               maxv[j] = maxv[j] - minv[i];

           }

        }

     

        //将包含负数的序列按借位方法变为正。max = {0,9,9,0}

        for (int i = maxv.size()-1; i > 0; i--)

        {

           if (maxv[i] < 0){

               maxv[i] += 10;

               maxv[i - 1] -= 1;

           }

        }

     

        /*输出*/

        if (!isPositive){

           cout << "-";

        }

        if (maxv[0] != 0){

           cout << maxv[0];

        }

        for (int i = 1; i < maxv.size(); i++)

        {

           cout << maxv[i];

        }

        return 0;

    }

     

     

     

    加法:

    /*

    高精度加法题目:http://codevs.cn/problem/3116/

    2015.5.5 shaonian.ding

    */

     

    #include<iostream>

    #include<vector>

    #include<string>

    usingnamespace std;

     

    //string convert to vector<int> function

    void strToInts(string str, vector<int> &v){

        int len = str.size();

        for (int i = 0; i < len; i++)

        {

           int c = str[i] - '0';

           v.push_back(c);

        }

    }

    int main(){

        string maxStr, minStr;

        /*test case*/

         //maxStr = "945";

         //minStr = "59";

       

        /*Input Data*/

        cin >> maxStr >> minStr;

     

        /*code*/

        vector<int> maxv, minv;//max vectormin vector

     

        if (maxStr.size() <= minStr.size()){

           swap(maxStr, minStr);

        };

     

        //string convert to ints

        strToInts(maxStr, maxv);

        strToInts(minStr, minv);

     

        //maxv = maxv - minv;高位开始加,得到序列max = {9,9,14}

        for (int i = 0; i < minv.size(); i++)

        {

           int j = maxv.size() - minv.size() + i;

           maxv[j] = maxv[j] + minv[i];

        }

     

        //max = {9,9,14}

        for (int i = maxv.size() - 1; i > 0; i--)

        {

           if (maxv[i] >= 10){//最多为19

               maxv[i] -= 10;

               maxv[i - 1] += 1;//i=1执行最后一次转换,maxv[0]可能等于10

           }

        }

     

        /*输出*/

        if (maxv[0] != 10){//跳过最高位为0

           cout << maxv[0];

        }

        else{

           cout << "1" << 10 - maxv[0];

        }

        for (int i = 1; i < maxv.size(); i++)

        {

           cout << maxv[i];

        }

        return 0;

    }

     

    乘法:

    /*

    高精度乘法题目:http://codevs.cn/problem/3117/

    2015.5.5 shaonian.ding

    */

    #include<iostream>

    #include<vector>

    #include<string>

    usingnamespace std;

     

    //string convert to vector<int> function

    void strToInts(string str, vector<int> &v){

        int len = str.size();

        for (int i = 0; i < len; i++)

        {

           int c = str[i] - '0';

           v.push_back(c);

        }

    }

    int main(){

        string maxStr, minStr;

     

    /*test case */

         //maxStr = "123";

         //minStr = "45";

     

         //maxStr = "99";

         //minStr = "99";

     

        /*Input Data*/

        cin >> maxStr >> minStr;

     

    /*code*/

        vector<int> maxv, minv;//max vectormin vector

     

        //string convert to ints

        strToInts(maxStr, maxv);

        strToInts(minStr, minv);

     

        int n = maxv.size() + minv.size();//乘积的位数(不会大于两乘数位数之和)

        vector<int> mul(n, 0 );//保存乘积multiplication,用来输出。

     

        /*

        *tset1:mul ={ 0,4,13,22,15 }

        *tset2:mul ={ 0,81,162,81}

        */

        for (int i = 0; i < minv.size(); i++)// min i 外循环

        {

           for (int j = 0; j < maxv.size(); j++)//max j 内循环

           {

               mul[i + j+1] += maxv[j] * minv[i];//

           }

        }

       

        /*

        *test1:mul = { 0,5,5,3,5 }

        *test2:mul = { 9,8,0,1 }

        */

        for (int i = mul.size() - 1; i > 0; i--)

        {

           if (mul[i] >= 100){//最多为199

               mul[i - 1] += mul[i] / 10;//进位

               mul[i] -= mul[i] / 10 *10;

           }elseif (mul[i] >= 10){//最多为99

               mul[i - 1] += mul[i] / 10;

               mul[i] -= mul[i] / 10 * 10;

           }

        }

     

    /*输出*/

        if (mul[0] != 0){//跳过最高位为0

           cout << mul[0];

        }

        for (int i = 1; i < mul.size(); i++)

        {

           cout << mul[i];

        }

        return 0;

    }

  • 相关阅读:
    mysql分区表批量添加/删除range按天分区(int类型)
    mysql分区表批量添加/删除range按天分区(datetime类型)
    使用obd离线安装oceanbase
    mysqldump导出数据自增属性丢失案例
    Docker启动镜像并设置开机自启
    Docker启动mysql与elasticsearch以及nginx的命令
    Redis学习--从节点过期键清理策略
    Redis学习--渐进式rehash实现原理
    Redis学习--主节点过期键清理策略
    Redis学习--慢日志信息
  • 原文地址:https://www.cnblogs.com/dingblog/p/4479571.html
Copyright © 2011-2022 走看看