zoukankan      html  css  js  c++  java
  • AcWing算法基础1.4

    高精度

    高精度加法,高精度减法,高精度乘低精度,高精度除以低精度,大概平时用的最多的就是这四个,模板有两种(因为我现在不太会用vector,就用数组也写了个,23333)

    高精度运算和人工手算差不多,就是模拟人工手算的过程,乘法有点不一样,在下面有提到,大致也是模拟运算

    废话不多说,上模板

    高精度加法

     1 // C = A + B, A >= 0, B >= 0
     2 vector<int> add(vector<int> &A, vector<int> &B)
     3 {
     4     if (A.size() < B.size()) return add(B, A);
     5     
     6     vector<int> C;
     7     int t = 0;
     8     for (int i = 0; i < A.size(); i ++ )
     9     {
    10         t += A[i];
    11         if (i < B.size()) t += B[i];
    12         C.push_back(t % 10);
    13         t /= 10;
    14     }
    15     
    16     if (t) C.push_back(t);
    17     return C;
    18 }

    高精度减法

     1 // C = A - B, 满足A >= B, A >= 0, B >= 0
     2 vector<int> sub(vector<int> &A, vector<int> &B)
     3 {
     4     vector<int> C;
     5     for (int i = 0, t = 0; i < A.size(); i ++ )
     6     {
     7         t = A[i] - t;
     8         if (i < B.size()) t -= B[i];
     9         C.push_back((t + 10) % 10);
    10         if (t < 0) t = 1;
    11         else t = 0;
    12     }
    13 
    14     while (C.size() > 1 && C.back() == 0) C.pop_back();
    15     return C;
    16 }

    这里高精度减法对于A < B 的情况我们特判下输出个 - 就好了,模板第九行是比较巧的一步,因为我们减一位后 t 的取值范围是(-10,10)t 可能是正数也可能是负数,对于正数我们可以直接拿来用,对于负数要向前面一位进1,相当于把 t 加10,这里写成(t + 10)% 10  就能把两种情况写在一起了

    高精度乘低精度

     1 // C = A * b, A >= 0, b > 0
     2 vector<int> mul(vector<int> &A, int b)
     3 {
     4     vector<int> C;
     5     int t = 0;
     6     for (int i = 0; i < A.size() || t; i ++ )
     7     {
     8         if (i < A.size()) t += A[i] * b;
     9         C.push_back(t % 10);
    10         t /= 10;
    11     }
    12     
    13     return C;
    14 }

    乘法和我们人模拟的算有点差别,比如156 * 23 算第一位的时候直接拿6 * 23,然后再拿5 * 23 + 进位,以此类推

    高精度除以低精度

     1 // A / b = C ... r, A >= 0, b > 0
     2 vector<int> div(vector<int> &A, int b, int &r)
     3 {
     4     vector<int> C;
     5     r = 0;
     6     for (int i = A.size() - 1; i >= 0; i -- )
     7     {
     8         r = r * 10 + A[i];
     9         C.push_back(r / b);
    10         r %= b;
    11     }
    12     reverse(C.begin(), C.end());
    13     while (C.size() > 1 && C.back() == 0) C.pop_back();
    14     return C;
    15 }

    上面是用vector的模板,对于不会用vector的我,用数组写了个,呃呃呃呃....

    高精度加法

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring> 
     4 
     5 using namespace std;
     6 int add(int a[], int b[]);
     7 const int N = 100000 + 10;
     8 char x1[N], x2[N];
     9 int a[N], b[N], c[N];
    10 
    11 int main()
    12 {
    13     scanf("%s%s",x1,x2);
    14     int len1 = strlen(x1), len2 = strlen(x2);
    15     for(int i = len1 - 1, j = 0; i >= 0; i --, j ++)
    16         a[j] = x1[i] - '0';
    17     for(int i = len2 - 1, j = 0; i >= 0; i --, j ++)
    18         b[j] = x2[i] - '0';
    19       
    20     int id = add(a, b);
    21     for(int i = id - 1; i >= 0; i --)
    22         printf("%d",c[i]);
    23     return 0;  
    24     //add(a,b);
    25     
    26 }
    27 
    28 int add(int a[], int b[])
    29 {
    30     int mx = 0, id = 0;
    31     if(strlen(x1) >= strlen(x2))  mx = strlen(x1);
    32     else  mx = strlen(x2);
    33     int t = 0;
    34     for(int i = 0; i < mx; i ++)
    35     {
    36         c[id++] = (a[i] + b[i] + t) % 10;
    37         t = (a[i] + b[i] + t) / 10;
    38     }
    39     if(t)  c[id++] = t;
    40     return id;
    41 }

    高精度减法

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring> 
     4 
     5 using namespace std;
     6 int mun(int a[], int b[]);
     7 bool cmp(int a[], int b[]); //用来比较a,b谁大,判断是输出正数还是负数
     8 const int N = 100000 + 10;
     9 char x[N], y[N];
    10 int a[N], b[N], c[N];
    11 
    12 int main()
    13 {
    14     scanf("%s%s",x,y);
    15     int lena = strlen(x), lenb = strlen(y);
    16     for(int i = lena - 1, j = 0; i >= 0; i --, j ++ )    a[j] = x[i] - '0';
    17     for(int i = lenb - 1, j = 0; i >= 0; i --, j ++ )    b[j] = y[i] - '0';
    18     
    19     if(cmp(a, b))  cout << "-";
    20     int temp = mun(a, b);
    21     for(int i = temp - 1; i >= 0; i -- )
    22         printf("%d",c[i]);
    23     return 0;
    24 }
    25 
    26 int mun(int a[], int b[])
    27 {
    28     if(cmp(a, b))  return (mun(b, a));
    29     
    30     int t = 0, mx = max(strlen(x), strlen(y));
    31     for(int i = 0; i < mx; i ++ )
    32     {
    33         t = a[i] - b[i] + t;
    34         c[i] = (t + 10) % 10;
    35         if(t < 0)  t = -1;
    36         else t = 0;
    37     }
    38     
    39     int id = mx;
    40     for(int i = mx - 1; i > 0; i --)  //去除前导零
    41     {
    42         if(c[i] == 0)  id -- ;
    43         else  break;
    44     }
    45     return id;                      //id是数组c的长度
    46 }
    47 
    48 bool cmp(int a[], int b[])
    49 {
    50     int mx = max(strlen(x), strlen(y));
    51     for(int i = mx - 1; i >= 0; i -- )
    52     {
    53         if(a[i] > b[i])  return 0;
    54         if(a[i] < b[i])  return 1;
    55     }
    56     return 0;
    57 }

    高精度乘法

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 
     5 
     6 using namespace std;
     7 int mul(int a[], int b);
     8 const int maxa = 100000 + 10;
     9 char x[maxa];
    10 int a[maxa], c[maxa], b;
    11 
    12 int main()
    13 {
    14     scanf("%s%d",x,&b);
    15     int lena = strlen(x);
    16     for(int i = lena - 1, j = 0; i >= 0; i --, j ++ )  a[j] = x[i] - '0';
    17     
    18     int id = mul(a, b);
    19     for(int i = id - 1; i >= 0; i -- )
    20         cout << c[i];
    21     return 0;
    22 }
    23 
    24 int mul(int a[], int b)
    25 {
    26     int t = 0, id = 0, lena = strlen(x);
    27     for(int i = 0; i < lena; i ++ )
    28     {
    29         t = a[i] * b + t;
    30         c[id++] = t % 10;
    31         t = t / 10;
    32     }
    33     if(t)  c[id++] = t;
    34     return id;
    35 }

    高精度除法

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 
     5 using namespace std;
     6 int div(int b[], int k);
     7 const int N = 100000 + 10;
     8 string a;
     9 int b[N], c[N], k, t;   //t是余数
    10 
    11 int main()
    12 {
    13     cin >> a >> k;
    14     for(int i = 0; i < a.size(); i ++ )   b[i] = a[i] - '0';
    15     
    16     int id = div(b, k);
    17     int q = 0;
    18     for(int i = 0; i < id - 1; i ++ )
    19         if(c[i] == 0)  q ++ ;
    20         else  break;
    21     for(int i = q; i < id; i ++ )
    22         printf("%d",c[i]);
    23     printf("
    %d",t);
    24     return 0;
    25 }
    26 
    27 int div(int b[], int k)
    28 {
    29     int id = 0;
    30     for(int i = 0; i < a.size(); i ++ )
    31     {
    32         t = t * 10 + b[i];
    33         c[id++] = t / k;
    34         t %= k;
    35     }
    36     return id;
    37 }

    输出两行,第一行是商,第二行是余数

  • 相关阅读:
    Linux下命令行安装weblogic10.3.6
    11g新特性:Health Monitor Checks
    Oracle/PLSQL: ORA-06550
    DBMS_NETWORK_ACL_ADMIN
    【RDA】使用RDA(Remote Diagnostic Agent)工具对数据库进行健康检查
    ORA-39242 错误
    Yii2 中常用的增删改查操作总结
    PHP递归函数return返回null的问题
    PHP中生成随机字符串,数字+大小写字母随机组合
    使用layer.msg 时间设置不起作用
  • 原文地址:https://www.cnblogs.com/chuyds/p/10972974.html
Copyright © 2011-2022 走看看