zoukankan      html  css  js  c++  java
  • 刘汝佳 算法竞赛-入门经典 第二部分 算法篇 第五章 2(Big Number)

    这里的高精度都是要去掉前导0的,

    第一题:424 - Integer Inquiry

    UVA:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=97&page=show_problem&problem=365

    解题思路:模拟手动加法的运算过程,写一个高精度整数加法就可以了;减法,乘法,除法同样也是模拟手动过程。

    解题代码:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <math.h>
     4 #include <algorithm>
     5 #include <string.h>
     6 #include <string>
     7 #include <map>
     8 using namespace std;
     9 
    10 //#define LOCAL  //Please annotate this line when you submit
    11 
    12 #ifdef WINDOWS
    13     #define LL __int64
    14     #define LLD "%I64d"
    15 #else
    16     #define LL long long
    17     #define LLD "%lld"
    18 #endif
    19 
    20 char num1[1000];
    21 int num2[1000],  ans[1000];
    22 
    23 int add()
    24 {
    25     int len = strlen(num1);
    26     if (len == 1 && num1[0] == '0')
    27         return 0;
    28     memset(num2, 0, sizeof(num2));
    29     int k = 0;
    30     for (int i = len - 1; i >= 0; i --)
    31     {
    32         num2[k++] = num1[i] - '0';
    33     }
    34     int up = 0;
    35     for (int i = 0; i < 1000; i ++)
    36     {
    37         ans[i] = ans[i] + num2[i] + up;
    38         up = ans[i]/10;
    39         ans[i] %= 10;
    40     }
    41     return 1;
    42 }
    43 
    44 int main()
    45 {
    46 
    47 #ifdef LOCAL
    48     freopen("data.in", "r", stdin);
    49     freopen("data.out", "w", stdout);
    50 #endif
    51     memset (ans, 0, sizeof(ans));
    52     int cun = 0;
    53     while (1)
    54     {
    55         scanf ("%s", num1);
    56         if (add())
    57             continue;
    58         else
    59         {
    60             int i;
    61             for (i = 999; i >= 0; i --)
    62                 if (ans[i])
    63                     break;
    64             for ( ; i >= 0; i --)
    65                 printf("%d", ans[i]);
    66             puts("");
    67             break;
    68         }
    69     }
    70     return 0;
    71 }
    View Code

     

    第二题:10106 - Product

    UVA:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=97&page=show_problem&problem=1047

    解题思路:此题是高精度整数乘法。

    解题代码:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <math.h>
     4 #include <algorithm>
     5 #include <string.h>
     6 #include <string>
     7 #include <map>
     8 using namespace std;
     9 
    10 //#define LOCAL  //Please annotate this line when you submit
    11 
    12 #ifdef WINDOWS
    13     #define LL __int64
    14     #define LLD "%I64d"
    15 #else
    16     #define LL long long
    17     #define LLD "%lld"
    18 #endif
    19 
    20 const int max_n = 1000;
    21 int num1[max_n], num2[max_n], ans[2*max_n];
    22 char str1[max_n], str2[max_n];
    23 
    24 void ride()
    25 {
    26     memset(num1, 0, sizeof(num1));
    27     memset(num2, 0, sizeof(num2));
    28     memset(ans, 0, sizeof(ans));
    29     int len1 = strlen(str1);
    30     int k = 0, i;
    31     for (i = len1-1; i >= 0; i--)
    32         num1[k++] = str1[i] - '0';
    33     int len2 = strlen(str2);
    34     for (i = len2 - 1, k = 0; i >= 0; i--)
    35         num2[k++] = str2[i] - '0';
    36     int up = 0;
    37     for (int j = 0; j < max_n; j ++)
    38     {
    39         for (i = 0; i < max_n; i ++)
    40         {
    41             ans[i+j] += num1[i]*num2[j] + up;
    42             up = ans[i+j]/10;
    43             ans[i+j] %= 10;
    44         }
    45     }
    46     for (i = 2*max_n-1; i >= 0; i --)
    47         if (ans[i])
    48             break;
    49     if (i < 0)
    50         i = 0;
    51     for ( ; i >= 0; i --)
    52         printf("%d", ans[i]);
    53     puts("");
    54 }
    55 
    56 int main()
    57 {
    58 
    59 #ifdef LOCAL
    60     freopen("data.in", "r", stdin);
    61     freopen("data.out", "w", stdout);
    62 #endif
    63     while (~scanf("%s", str1))
    64     {
    65         scanf("%s", str2);
    66         ride();
    67     }
    68     return 0;
    69 }
    View Code

    第三题:465 - Overflow

    UVA:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=97&page=show_problem&problem=406

    解题思路:

        此题也是高精度加法,乘法。当然晚上有用atof秒杀的,既然是专题,还是写个高精度吧!这题也需要去掉前导0,比较与int型大小时,条件要判断好,我在这个条件这里因为少写了一个if语句结果WA了n次。o(╯□╰)o

    ps:int数据最大值是2147483647;

    解题代码:

      1 #ifdef WINDOWS
      2     #define LL __int64
      3     #define LLD "%I64d"
      4 #else
      5     #define LL long long
      6     #define LLD "%lld"
      7 #endif
      8 //#define LOCAL  //Please annotate this line when you submit
      9 /********************************************************/
     10 #include <iostream>
     11 #include <stdio.h>
     12 #include <math.h>
     13 #include <algorithm>
     14 #include <string.h>
     15 #include <string>
     16 #include <map>
     17 using namespace std;
     18 const int max_n = 20000;
     19 int num1[max_n], num2[max_n], ans[max_n];
     20 char str1[max_n], str2[max_n], ope;
     21 bool jug1, jug2, juga;
     22 const int MAX[10] = {7,4,6,3,8,4,7,4,1,2};
     23 int pos1, pos2;
     24 
     25 void add()
     26 {
     27     int up = 0;
     28     int i;
     29     int t = pos1 > pos2 ? pos1 : pos2;
     30     for (i = 0; i <= t+1; i ++)
     31     {
     32         ans[i] = num1[i] + num2[i] + up;
     33         up = ans[i]/10;
     34         ans[i] %= 10;
     35     }
     36     for (i = t+1; i >= 0; i --)
     37         if (ans[i])
     38             break;
     39 /*
     40     for (int j = i; j >= 0; j --)
     41         cout << ans[j];
     42     cout << endl;
     43 */
     44     if (i > 9)
     45         juga = true;
     46     else if (i == 9)
     47         for (i = 9; i >= 0; i --)
     48         {
     49             if (ans[i] > MAX[i])
     50             {
     51                 juga = true;
     52                 break;
     53             }
     54             if (ans[i] < MAX[i])
     55                 break;
     56         }
     57 }
     58 
     59 void mul()
     60 {
     61     int up = 0;
     62     int i;
     63     for (i = 0; i <= pos1 + 1; i ++)
     64         for (int j = 0; j <= pos2 + 1; j ++)
     65         {
     66             ans[i+j] += num1[i]*num2[j] + up;
     67             up = ans[i+j]/10;
     68             ans[i+j] %= 10;
     69         }
     70     for (i = pos1+pos2+2; i >= 0; i --)
     71         if (ans[i])
     72             break;
     73 /*
     74     for (int j = i; j >= 0; j --)
     75         cout << ans[j];
     76     cout << endl;
     77 */
     78     if (i > 9)
     79         juga = true;
     80     else if (i == 9)
     81         for (; i >= 0; i --)
     82         {
     83             if (ans[i] > MAX[i])
     84             {
     85                 juga = true;
     86                  break;
     87             }
     88             if (ans[i] < MAX[i])
     89                 break;
     90         }
     91 }
     92 
     93 int main()
     94 {
     95 #ifdef LOCAL
     96     freopen("data.in", "r", stdin);
     97     freopen("data.out", "w", stdout);
     98 #endif
     99     while (~scanf ("%s %c %s", str1, &ope, str2))
    100     {
    101         jug1 = jug2 = juga = false;
    102         memset(num1, 0, sizeof (num1));
    103         memset(num2, 0, sizeof (num2));
    104         memset (ans, 0, sizeof (ans));
    105         pos1 = 0;
    106         for (int i = strlen(str1) - 1, k = 0; i >= 0; i --)
    107         {
    108             num1[k ++] = str1[i] - '0';
    109             if (num1[k-1])
    110                 pos1 = k - 1;
    111         }
    112         if (pos1 > 9)
    113         {
    114             juga = true;
    115             jug1 = true;
    116         }
    117         else if(pos1 == 9)
    118         {
    119             for (int i = 9; i >= 0; i --)
    120             {
    121                 if (num1[i] > MAX[i])
    122                 {
    123                     juga = true;
    124                     jug1 = true;
    125                     break;
    126                 }
    127                 if (num1[i] < MAX[i])
    128                     break;
    129             }
    130         }
    131         pos2 = 0;
    132         for (int i = strlen(str2) - 1, k = 0; i >= 0; i --)
    133         {
    134             num2[k ++] = str2[i] - '0';
    135             if (num2[k-1])
    136                 pos2 = k-1;
    137         }
    138         if (pos2 > 9)
    139         {
    140             jug2 = true;
    141             juga = true;
    142         }
    143         else if (pos2 == 9)
    144         {
    145             for (int i = 9; i >= 0; i--)
    146             {
    147                 if (num2[i] > MAX[i])
    148                 {
    149                     juga = true;
    150                     jug2 = true;
    151                     break;
    152                 }
    153                 if (num2[i] < MAX[i])
    154                     break;
    155             }
    156         }
    157         if ((pos1 == 0 && num1[pos1] == 0) || (pos2 == 0 && num2[pos2] == 0))
    158             juga = false;
    159         printf("%s %c %s
    ", str1, ope, str2);
    160         if (ope == '+')
    161             add();
    162         else if (ope == '*')
    163             mul();
    164         else if (ope != '+' && ope != '*')
    165             juga = false;
    166         if (jug1)
    167             printf("first number too big
    ");
    168         if (jug2)
    169             printf("second number too big
    ");
    170         if (juga)
    171             printf("result too big
    ");
    172     }
    173 
    174     return 0;
    175 }
    View Code

    第四题:748 - Exponentiation

     UVA:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=97&page=show_problem&problem=689

    解题思路:高精度乘法;但这里是浮点型,我们只需把小数点去了,进行计算,输出时再找准小数点位置输出就可,至于小数点位置的话,举个列子:13.4*3.54,两个数长度都是4第一个数字小数点在 2 的位置,小数点位数为 4-2-1 = 1;第二个数小数点在 1 的位置,小数点位数为 4 - 1 - 1 = 2;他们的乘积为 47.436,小数点的位数为 3 = 1 + 2;也就是数字一的位数与数字二的位数的和。此题还需将后缀0去掉。

    解题代码:

      1 #ifdef WINDOWS
      2     #define LL __int64
      3     #define LLD "%I64d"
      4 #else
      5     #define LL long long
      6     #define LLD "%lld"
      7 #endif
      8 //#define LOCAL  //Please annotate this line when you submit
      9 /********************************************************/
     10 #include <iostream>
     11 #include <stdio.h>
     12 #include <math.h>
     13 #include <algorithm>
     14 #include <string.h>
     15 #include <string>
     16 #include <map>
     17 using namespace std;
     18 const int max_n = 1000;
     19 string str;
     20 int num1[max_n], num2[max_n], ans[2*max_n];
     21 int point, Pow;
     22 int len1, len2;
     23 
     24 void change()
     25 {
     26     memset(num1, 0, sizeof(num1));
     27     memset(num2, 0, sizeof(num2));
     28     point = str.find(".");
     29     int len = str.length();
     30     if (point != -1)
     31         point = len - point - 1;
     32     int k = 0;
     33     for (int i = len - 1; i >= 0; i --)
     34     {
     35         if (str[i] == '.')
     36             continue;
     37         num1[k] = str[i] - '0';
     38         num2[k ++] = str[i] - '0';
     39     }
     40     len1 = len2 = k;
     41 }
     42 
     43 void mult()
     44 {
     45     memset(ans, 0, sizeof (ans));
     46     int up = 0;
     47     for (int i = 0; i <= len1; i ++)
     48         for (int j = 0; j <= len2; j ++)
     49         {
     50             ans[i+j] += num1[i]*num2[j] + up;
     51             up = ans[i+j]/10;
     52             ans[i+j] %= 10;
     53         }
     54     int bg;
     55     for (int i = len1 + len2; i >= 0; i--)
     56         if (ans[i])
     57         {
     58             bg = i;
     59             break;
     60         }
     61             
     62     for (int i = 0; i <= bg; i ++)
     63         num2[i] = ans[i];
     64     len2 = bg + 1;    
     65 }
     66 
     67 void output()
     68 {
     69     int i, j, k;
     70     for (i = max_n-1; i >=0; i--)
     71     {
     72         if(num2[i])
     73             break;
     74         if (i == Pow*point)
     75         {
     76             i --;
     77             break;
     78         }
     79     }
     80     for (j = 0; j <= i; j ++)
     81     {
     82         if (num2[j])
     83             break;
     84         if (j == Pow*point)
     85         {
     86             j ++;
     87             break;
     88         }
     89     }
     90     if (i+1 == Pow * point)
     91         printf(".");
     92     for (k = i; k >= j; k --)
     93     {
     94         printf("%d", num2[k]);
     95         if (k == Pow*point && k > j)
     96             printf(".");
     97     }
     98     printf("
    ");
     99 }
    100 
    101 int main()
    102 {
    103 #ifdef LOCAL
    104     freopen("data.in", "r", stdin);
    105     freopen("data.out", "w", stdout);
    106 #endif
    107     while (cin >> str)
    108     {
    109         scanf ("%d", &Pow);
    110         change();
    111         for (int i = 1; i < Pow; i ++)
    112             mult();
    113         output();
    114     }
    115     return 0;
    116 }
    View Code

     

    第五题:10494 - If We Were a Child Again

    UVA:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=97&page=show_problem&problem=1435

    解题思路:此题是高精度除法,题目只需高精度除以低精度,但我想练习一下就写了高精度除以高精度,过程是模拟短除法来做,配合高精度正整数减法。此题题意里除数没有包含0,但数据里我想应该是有的,因为我少了为0的判断就WA,加上就AC。所以0做为除数还是要判断一下。

    解题代码:

      1 //#define LOCAL  //Please annotate this line when you submit
      2 #ifdef WINDOWS
      3     #define LL __int64
      4     #define LLD "%I64d"
      5 #else
      6     #define LL long long
      7     #define LLD "%lld"
      8 #endif
      9 
     10 /********************************************************/
     11 #include <iostream>
     12 #include <stdio.h>
     13 #include <math.h>
     14 #include <algorithm>
     15 #include <string.h>
     16 #include <string>
     17 #include <map>
     18 #define CLE(name) memset(name, 0, sizeof(name))
     19 using namespace std;
     20 
     21 const int max_n = 1000;
     22 int num1[max_n], num2[max_n], num3[max_n];//被除数和除数 
     23 int len1, len2, len3;
     24 string str1, ope, str2;
     25 int len_str1, len_str2;
     26 int get_num_pos;
     27 int quo[max_n], res[max_n];//商和余数
     28 int len_quo, len_res;
     29 bool had_red;
     30 
     31 bool get_num3()
     32 {    
     33     int i, k, j;
     34     k = 0;
     35     len3 ++;
     36     if (get_num_pos + len3 > len1)
     37     {
     38         for (i = len3 - 1; i >= 0; i --)
     39             if (num3[i])
     40                 break;
     41         for (j = i; j >= 0; j --)
     42             res[len_res++] = num3[j];
     43         return false;
     44     }
     45     for (i = get_num_pos + len3 - 1; i >= get_num_pos; i --)
     46         num3[k ++] = num1[i];
     47     return true;
     48 }
     49 
     50 bool cpt()//将余数补在num1上 
     51 {
     52     int i, j;
     53     for (i = get_num_pos - 1, j = len_res - 1; j >= 0; j --, i --)
     54         num1[i] = res[j];
     55     get_num_pos = i + 1;
     56     if (get_num3())
     57     {
     58         for (i = 0; i < len_res; i ++)
     59             res[i] = 0;
     60         len_res = 0;
     61         return true;
     62     }
     63     else return false;
     64 }
     65 
     66 void change()
     67 {
     68     CLE(num1);    CLE(num2);
     69     CLE(num3);    CLE(res);    CLE(quo);
     70     
     71     len_str1 = str1.length();
     72     len_str2 = str2.length();
     73     int k = 0;
     74     bool had = false;
     75     for (int i = 0; i < len_str1; i ++)
     76     {
     77         if (str1[i] == '0' && !had)
     78             continue;
     79         else
     80         {
     81             num1[k++] = str1[i] - '0';
     82             had = true;
     83         }
     84     }
     85     len1 = k;
     86     k = 0;
     87     int bg = 0;
     88     for(int i = 0; i < len_str2; i ++)
     89         if (str2[i] != '0')
     90         {
     91             bg = i;
     92             break;
     93         }
     94     for (int i = len_str2 - 1; i >= bg; i --)
     95         num2[k++] = str2[i] - '0';
     96     len2 = k;
     97 }
     98 
     99 bool cmp()
    100 {
    101     if (len2 > len3)
    102         return false;
    103     else if(len3 > len2)
    104     {
    105         if (num3[len3 - 1] == 0)
    106             return false;
    107         return true;
    108     }
    109     else
    110     {
    111         for (int i = len2 - 1; i >= 0; i --)
    112         {
    113             if (num2[i] > num3[i])
    114                 return false;
    115             if (num2[i] < num3[i])
    116                 return true;
    117         }
    118     }
    119     return true;
    120 }
    121 
    122 bool cmp_input()
    123 {
    124     if (len2 == 1 && num2[0] == 0)
    125         return false;
    126     if (len1 < len2)
    127         return false;
    128     if (len1 == len2)
    129     {
    130         for (int i = 0; i < len1; i ++)
    131         {
    132             if (num1[i] > num2[len2 - i -1])
    133                 return true;
    134             if (num1[i] < num2[len2 - i - 1])
    135                 return false;
    136         }
    137     }
    138     return true;
    139 }
    140 
    141 void red()
    142 {
    143     int reduce_num = 0;
    144     if (cmp())
    145     {
    146         get_num_pos += len3;
    147         do
    148         {
    149             had_red = true;
    150             int up = 0;
    151             for (int i = 0; i < len3; i ++)
    152             {
    153                 num3[i] = num3[i] - num2[i] - up;
    154                 if (num3[i] < 0)
    155                 {
    156                     num3[i] += 10;
    157                     up = 1;
    158                 }
    159                 else up = 0;
    160             }
    161             int i;
    162             for (i = len3 - 1; i >= 0; i --)
    163                 if (num3[i])
    164                 {
    165                     len3 = i + 1;
    166                     break;
    167                 }
    168             if (i < 0)
    169                 len3 = 0;
    170             reduce_num ++;
    171         }while(cmp());
    172         quo[len_quo++] = reduce_num;
    173         int k = 0;
    174         for (int i = len3 - 1; i >= 0; i --)
    175         {
    176             res[k ++] = num3[i];
    177             num3[i] = 0;
    178         }
    179         len_res = len3;
    180         if(cpt())
    181             red();
    182         else return;
    183     }
    184     else
    185     {
    186         if (had_red)
    187             quo[len_quo ++] = 0;
    188         if (len3 == 1 && num3[0] == 0)
    189         {
    190             len3 = 0;
    191             get_num_pos ++;    
    192         }
    193         if (get_num3())
    194             red();
    195     }
    196     return;
    197 }
    198 
    199 void output()
    200 {
    201     int i, j;
    202     if (len_quo == 0)
    203         len_quo = 1;
    204     if (len_res == 0)
    205         len_res = 1;
    206     if (ope[0] == '/')
    207     {
    208         for (int i = 0; i < len_quo; i ++)
    209             printf("%d", quo[i]);
    210         puts("");
    211     }
    212     else if (ope[0] == '%')
    213     {
    214         for (i = 0; i < len_res; i ++)
    215             printf("%d", res[i]);
    216         puts("");
    217     }
    218     return;
    219 }
    220 
    221 int main()
    222 {
    223 #ifdef LOCAL
    224     freopen("data.in", "r", stdin);
    225     freopen("data.out", "w", stdout);
    226 #endif
    227     while (cin >> str1 >> ope >> str2)
    228     {
    229         had_red = false;
    230         len_quo = 0;
    231         len_res = 0;
    232         len3 = 0;
    233         get_num_pos = 0;
    234         change();
    235         if (cmp_input())
    236             red();
    237         else
    238             for (int i = 0; i < len1; i ++)
    239                 res[len_res++] = num1[i];
    240         output();
    241     }    
    242 
    243     return 0;
    244 }
    View Code

    此题附上几组数据:

    input:

    8947186453786576673428174634 / 2147483647
    1672563736 / 176317
    17673764 / 74376
    178226322222245124732648484 % 8276424
    24969 / 123
    100100 / 10
    0 / 123
    1002 % 10
    1324211111111111111 / 456679284
    21474836447 / 2147483647

    output:

    4166358363792735634
    9486
    237
    3883828
    203
    10010
    0
    2
    2899652245
    9

  • 相关阅读:
    微前端的那些事儿
    网络是怎样连接的 作者户根勤 交流论坛
    数据结构与算法学习
    cpu读取指令时读取的长度
    小程序开发
    npm 安装 chromedriver 失败的解决办法
    Git:代码冲突常见解决方法
    Android通过Chrome Inspect调试WebView的H5 App出现空白页面的解决方法(不需要FQ)
    pm2
    多媒体技术及应用
  • 原文地址:https://www.cnblogs.com/shengshouzhaixing/p/3216754.html
Copyright © 2011-2022 走看看