• 高精度算法总结


    一句话:只需将两个大数按照竖式模拟计算即可!

    高精度加法:

    题解报告:hdu 1002 A + B Problem II

    Problem Description

    I have a very simple problem for you. Given two integers A and B, your job is to calculate the Sum of A + B.

    Input

    The first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line consists of two positive integers, A and B. Notice that the integers are very large, that means you should not process them by using 32-bit integer. You may assume the length of each integer will not exceed 1000.

    Output

    For each test case, you should output two lines. The first line is "Case #:", # means the number of the test case. The second line is the an equation "A + B = Sum", Sum means the result of A + B. Note there are some spaces int the equation. Output a blank line between two test cases.

    Sample Input

    2
    1 2
    112233445566778899 998877665544332211

    Sample Output

    Case 1:
    1 + 2 = 3
     
    Case 2:
    112233445566778899 + 998877665544332211 = 1111111111111111110
    解题思路:大数加法,简单模拟竖式运算或者直接调用java中BigInteger大数类的add()方法即可。
    AC之C++代码:时间复杂度为O(n)。
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <cmath>
     5 #include <iostream>
     6 #include <algorithm>
     7 #include <iomanip>
     8 #include <complex>
     9 #include <string>
    10 #include <vector>
    11 #include <set>
    12 #include <map>
    13 #include <list>
    14 #include <deque>
    15 #include <queue>
    16 #include <stack>
    17 using namespace std;
    18 typedef long long LL;
    19 typedef unsigned long long ULL;
    20 const double eps = 1e-6;
    21 const double PI = acos(-1.0);
    22 const int maxn = 1e5+5;
    23 const int inf = 0x3f3f3f3f;
    24 
    25 int t, now, tmp;
    26 string a, b, r;
    27 bool flag;
    28 
    29 int main(){
    30     while(cin >> t){
    31         flag = true;
    32         for(int i = 1; i <= t; ++i){
    33             cin >> a >> b;
    34             tmp = 0, r = "";
    35             if(!flag) puts("");
    36             cout << "Case " << i << ":
    " << a << " + " << b << " = ";
    37             if(a.size() > b.size()) swap(a, b);
    38             for(int i = a.size() - 1, j = b.size() - 1; ~j; --i, --j){
    39                 now = (i >= 0 ? a[i] - '0' : 0) + b[j] - '0' + tmp;
    40                 tmp = now > 9 ? 1 : 0;
    41                 now = now > 9 ? now - 10 : now;
    42                 r += '0' + now;
    43             }
    44             if(tmp) r += '1'; //如果还有进位,则高位补1
    45             for(int i = r.size() - 1; ~i; --i) cout << r[i];
    46             puts(""); flag = false;
    47         }
    48     }
    49     return 0;
    50 }
    View Code

    AC之java代码:

     1 import java.util.Scanner;
     2 import java.math.BigInteger;
     3 public class Main {
     4     public static void main(String[] args) {
     5         Scanner scan = new Scanner(System.in);
     6         int t = scan.nextInt();
     7         BigInteger a, b;
     8         for(int i = 1; i <= t; ++i){
     9             a = scan.nextBigInteger();
    10             b = scan.nextBigInteger();
    11             System.out.println("Case " + i + ":");
    12             System.out.println(a + " + " + b + " = " + a.add(b));
    13             if(i != t) System.out.println();
    14         }    
    15     }
    16 }
    View Code

    高精度乘法:

    蓝桥杯 算法提高 P1001  

    时间限制:1.0s   内存限制:256.0MB
    当两个比较大的整数相乘时,可能会出现数据溢出的情形。为避免溢出,可以采用字符串的方法来实现两个大数之间的乘法。具体来说,首先以字符串的形式输入两个整数,每个整数的长度不会超过8位,然后把它们相乘的结果存储在另一个字符串当中(长度不会超过16位),最后把这个字符串打印出来。例如,假设用户输入为:62773417和12345678,则输出结果为:774980393241726.
    输入:
    62773417 12345678
    输出:
    774980393241726
    注意:特判输入有0的情况!
    AC之C++代码:时间复杂度为O(n^2)。此方法适用于两个位数不大的大数做乘法运算。(没有做压位运算)
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <cmath>
     5 #include <iostream>
     6 #include <algorithm>
     7 #include <iomanip>
     8 #include <complex>
     9 #include <string>
    10 #include <vector>
    11 #include <set>
    12 #include <map>
    13 #include <list>
    14 #include <deque>
    15 #include <queue>
    16 #include <stack>
    17 using namespace std;
    18 typedef long long LL;
    19 typedef unsigned long long ULL;
    20 const double eps = 1e-6;
    21 const double PI = acos(-1.0);
    22 const int maxn = 10;
    23 const int inf = 0x3f3f3f3f;
    24 
    25 char s1[maxn], s2[maxn];
    26 int m1, m2, a[maxn], b[maxn], carry, ans[maxn << 1]; //2倍
    27 bool flag;
    28 
    29 int main() {
    30     while(cin >> s1 >> s2) {
    31         memset(ans, 0, sizeof(ans));
    32         memset(a, 0, sizeof(a));
    33         memset(b, 0, sizeof(b));
    34         m1 = strlen(s1), m2 = strlen(s2), carry = 0;
    35         if((m1 == 1 && s1[0] == '0') || (m2 == 1 && s2[0] == '0')) {puts("0"); continue;} //特判0
    36         for(int i = m1 - 1; ~i; --i) a[m1 - 1 - i] = s1[i] - '0';
    37         for(int i = m2 - 1; ~i; --i) b[m2 - 1 - i] = s2[i] - '0';
    38         for(int i = 0; i < m2; ++i) {
    39             for(int j = 0; j < m1; ++j) {
    40                 ans[j + i] += a[j] * b[i] + carry;
    41                 if(ans[j + i] > 9) carry = ans[j + i] / 10, ans[j + i] %= 10;
    42                 else carry = 0;
    43             }
    44             if(carry) ans[i + m1] += carry, carry = 0;
    45         }
    46         flag = false;
    47         for(int i = m1 + m2 - 1; ~i; --i) { //最多有m1 + m2位数
    48             if(!flag && !ans[i]) continue;
    49             flag = true;
    50             cout << ans[i];
    51         }
    52         puts("");
    53     }
    54     return 0;
    55 }
    View Code

    AC之java代码:

     1 import java.util.Scanner;
     2 import java.math.BigInteger;
     3 public class Main {
     4     public static void main(String[] args){
     5         Scanner scan = new Scanner(System.in);
     6         BigInteger a, b;
     7         while(scan.hasNext()) {
     8             a = scan.nextBigInteger();
     9             b = scan.nextBigInteger();
    10             System.out.println(a.multiply(b));
    11         }
    12     }
    13 }
    View Code

    题解报告:hdu 1042 N!

    Problem Description

    Given an integer N(0 ≤ N ≤ 10000), your task is to calculate N!

    Input

    One N in one line, process to the end of file.

    Output

    For each N, output N! in one line.

    Sample Input

    1 2 3

    Sample Output

    1 2 6
    AC之C++代码:高精度乘法压5位。
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <cmath>
     5 #include <iostream>
     6 #include <algorithm>
     7 #include <iomanip>
     8 #include <complex>
     9 #include <string>
    10 #include <vector>
    11 #include <set>
    12 #include <map>
    13 #include <list>
    14 #include <deque>
    15 #include <queue>
    16 #include <stack>
    17 using namespace std;
    18 typedef long long LL;
    19 typedef unsigned long long ULL;
    20 const double eps = 1e-6;
    21 const double PI = acos(-1.0);
    22 const int maxn = 7200; // log_10^(10000!) ≈ 35560,压5位,则最多存35560 / 5 约等于7200
    23 const int inf = 0x3f3f3f3f;
    24 
    25 int n, cnt, carry, ans[maxn];
    26 
    27 int main() {
    28     while(cin >> n) {
    29         memset(ans, 0, sizeof(ans));
    30         cnt = carry = 0;
    31         ans[cnt++] = 1;
    32         for(int i = 2; i <= n; ++i) {
    33             for(int j = 0; j < cnt; ++j) {
    34                 ans[j] = ans[j] * i + carry; // 先乘再累加进位
    35                 if(ans[j] > 99999) carry = ans[j] / 100000, ans[j] %= 100000;
    36                 else carry = 0;
    37             }
    38             if(carry) ans[cnt++] = carry, carry = 0; //放到下一位,同时进位置0
    39         }
    40         printf("%d", ans[cnt - 1]); //先输出最高位,余下五位五位输出
    41         for(int j = cnt - 2; j >= 0; --j)
    42             printf("%05d", ans[j]); // 不足补0
    43         puts("");
    44     }
    45     return 0;
    46 }
    View Code

    高精度减法:

    luogu P2142 高精度减法

    题目描述

    高精度减法

    输入格式:
    两个整数a,b(第二个可能比第一个大)

    输出格式:
    结果(是负数要输出负号)

    输入输出样例
    输入样例#1:
    2
    1
    输出样例#1:
    1
    说明
    20%数据a,b在long long范围内
    100%数据0<a,b<=10的10000次方

    AC之C++代码:时间复杂度是O(n)。注意:做减法时,被减数要大于减数!!!

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <cmath>
     5 #include <iostream>
     6 #include <algorithm>
     7 #include <iomanip>
     8 #include <complex>
     9 #include <string>
    10 #include <vector>
    11 #include <set>
    12 #include <map>
    13 #include <list>
    14 #include <deque>
    15 #include <queue>
    16 #include <stack>
    17 using namespace std;
    18 typedef long long LL;
    19 typedef unsigned long long ULL;
    20 const double eps = 1e-6;
    21 const double PI = acos(-1.0);
    22 const int maxn = 1e4+5;
    23 const int inf = 0x3f3f3f3f;
    24 
    25 char s1[maxn], s2[maxn];
    26 int m1, m2, maxL, a[maxn], b[maxn], ans[maxn];
    27 bool op1, op2, flag;
    28 
    29 int main() {
    30     while(cin >> s1 >> s2) {
    31         memset(a, 0, sizeof(a));
    32         memset(b, 0, sizeof(b));
    33         memset(ans, 0, sizeof(ans));
    34         if(!strcmp(s1, s2)) {puts("0"); continue;}
    35         op1 = (s1[0] == '-') ? true : false;
    36         op2 = (s2[0] == '-') ? true : false;
    37         m1 = strlen(s1), m2 = strlen(s2);
    38         for(int i = op1 ? 1 : 0, k = op1 ? 0 : 1; i < m1; ++i) a[i - !k] = (s1[m1 - k - i] - '0');
    39         for(int i = op2 ? 1 : 0, k = op2 ? 0 : 1; i < m2; ++i) b[i - !k] = (s2[m2 - k - i] - '0');
    40         maxL = max(m1, m2);
    41         if((op1 && !op2) || (!op1 && op2)) { // 负、正 --> 负;正、负 --> 正
    42             if(op1 && !op2) cout << '-';
    43             for(int j = 0; j < maxL; ++j) { //加法运算
    44                 ans[j] += a[j] + b[j];
    45                 ans[j + 1] += ans[j] > 9 ? 1 : 0; //进位
    46                 ans[j] = ans[j] > 9 ? ans[j] - 10 : ans[j];
    47             }
    48         }
    49         else {
    50             if(!op1) {
    51                 if(m1 < m2 || (m1 == m2 && strcmp(s1, s2) < 0)) cout << '-', swap(a, b); //正、正 --> 正,交换
    52             }
    53             else if(op2) {
    54                 if(m1 > m2 || (m1 == m2 && strcmp(s1, s2) > 0)) cout << '-'; //负、负 --> s1 > s2 -- > 负数,不交换
    55                 else swap(a, b);
    56             }
    57             for(int j = 0; j < maxL; ++j) { //减法运算
    58                 if(a[j] < b[j]) a[j + 1]--, a[j] += 10; //借位
    59                 ans[j] = a[j] - b[j];
    60             }
    61         }
    62         flag = false;
    63         for(int j = maxL; ~j; --j) { //多处理一个进位项的系数
    64             if(!flag && !ans[j]) continue; //去掉前导0
    65             flag = true;
    66             cout << ans[j];
    67         }
    68         puts("");
    69     }
    70     return 0;
    71 }
    View Code

    AC之java代码:

     1 import java.util.Scanner;
     2 import java.math.BigInteger;
     3 public class Main {
     4     public static void main(String[] args){
     5         Scanner scan = new Scanner(System.in);
     6         BigInteger a, b;
     7         while(scan.hasNext()) {
     8             a = scan.nextBigInteger();
     9             b = scan.nextBigInteger();
    10             System.out.println(a.subtract(b));
    11         }
    12     }
    13 }
    View Code
  • 相关阅读:
    MQTT---HiveMQ源代码具体解释(四)插件载入
    HTTP访问控制(CORS)
    java实现限流
    Orika的使用姿势,Orika java bean copy 框架
    uploadify是通过flash上传,服务器获取type为application/octet-stream
    ThinkPHP 5使用 Composer 组件名称可以从https://packagist.org/ 搜索到
    3种方法轻松处理php开发中emoji表情的问题
    解决thinkphp设置session周期无效的问题
    如何使用沙箱测试单笔转账到支付宝账号(php版) https://openclub.alipay.com/read.php?tid=1770&fid=28
    微信jssdk批量添加卡券接口
  • 原文地址:https://www.cnblogs.com/acgoto/p/9483425.html
Copyright © 2020-2023  润新知