刘汝佳 算法竞赛-入门经典 第二部分 算法篇 第五章 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\n", 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\n");
168         if (jug2)
169             printf("second number too big\n");
170         if (juga)
171             printf("result too big\n");
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("\n");
 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

 

posted on 2013-07-26 11:36  圣手摘星  阅读(408)  评论(0编辑  收藏  举报

导航