唉,高精度前前后后加起来忙活了一整天,累啊、疲啊、乏啊。。。。

但为了AC事业,还是值了。。。。

  1. #include <stdio.h>

  2. #include <string.h>

  3. #include <stdlib.h>

  4. #include <math.h>

  5. #include <assert.h>

  6. #include <ctype.h>

  7. #include <map>

  8. #include <string>

  9. #include <set>

  10. #include <bitset>

  11. #include <utility>

  12. #include <algorithm>

  13. #include <vector>

  14. #include <stack>

  15. #include <queue>

  16. #include <iostream>

  17. #include <fstream>

  18. #include <list>

  19. usingnamespace  std;  

  20. constint MAXL = 500;  

  21. struct  BigNum  

  22. {  

  23. int  num[MAXL];  

  24. int  len;  

  25. };  

  26. //高精度比较 a > b return 1, a == b return 0; a < b return -1;

  27. int  Comp(BigNum &a, BigNum &b)  

  28. {  

  29. int  i;  

  30. if(a.len != b.len) return (a.len > b.len) ? 1 : -1;  

  31. for(i = a.len-1; i >= 0; i--)  

  32. if(a.num[i] != b.num[i]) return  (a.num[i] > b.num[i]) ? 1 : -1;  

  33. return  0;  

  34. }  

  35. //高精度加法

  36. BigNum  Add(BigNum &a, BigNum &b)  

  37. {  

  38.    BigNum c;  

  39. int  i, len;  

  40.    len = (a.len > b.len) ? a.len : b.len;  

  41.    memset(c.num, 0, sizeof(c.num));  

  42. for(i = 0; i < len; i++)  

  43.    {  

  44.        c.num[i] += (a.num[i]+b.num[i]);  

  45. if(c.num[i] >= 10)  

  46.        {  

  47.            c.num[i+1]++;  

  48.            c.num[i] -= 10;  

  49.        }  

  50.    }  

  51. if(c.num[len])  

  52.        len++;  

  53.    c.len = len;  

  54. return  c;  

  55. }  

  56. //高精度减法,保证a >= b

  57. BigNum Sub(BigNum &a, BigNum &b)  

  58. {  

  59.    BigNum  c;  

  60. int  i, len;  

  61.    len = (a.len > b.len) ? a.len : b.len;  

  62.    memset(c.num, 0, sizeof(c.num));  

  63. for(i = 0; i < len; i++)  

  64.    {  

  65.        c.num[i] += (a.num[i]-b.num[i]);  

  66. if(c.num[i] < 0)  

  67.        {  

  68.            c.num[i] += 10;  

  69.            c.num[i+1]--;  

  70.        }  

  71.    }  

  72. while(c.num[len] == 0 && len > 1)  

  73.        len--;  

  74.    c.len = len;  

  75. return  c;  

  76. }  

  77. //高精度乘以低精度,当b很大时可能会发生溢出int范围,具体情况具体分析

  78. //如果b很大可以考虑把b看成高精度

  79. BigNum Mul1(BigNum &a, int  &b)  

  80. {  

  81.    BigNum c;  

  82. int  i, len;  

  83.    len = a.len;  

  84.    memset(c.num, 0, sizeof(c.num));  

  85. //乘以0,直接返回0

  86. if(b == 0)  

  87.    {  

  88.        c.len = 1;  

  89. return  c;  

  90.    }  

  91. for(i = 0; i < len; i++)  

  92.    {  

  93.        c.num[i] += (a.num[i]*b);  

  94. if(c.num[i] >= 10)  

  95.        {  

  96.            c.num[i+1] = c.num[i]/10;  

  97.            c.num[i] %= 10;  

  98.        }  

  99.    }  

  100. while(c.num[len] > 0)  

  101.    {  

  102.        c.num[len+1] = c.num[len]/10;  

  103.        c.num[len++] %= 10;  

  104.    }  

  105.    c.len = len;  

  106. return  c;  

  107. }  

  108. //高精度乘以高精度,注意要及时进位,否则肯能会引起溢出,但这样会增加算法的复杂度,

  109. //如果确定不会发生溢出, 可以将里面的while改成if

  110. BigNum  Mul2(BigNum &a, BigNum &b)  

  111. {  

  112. int i, j, len = 0;  

  113.    BigNum  c;  

  114.    memset(c.num, 0, sizeof(c.num));  

  115. for(i = 0; i < a.len; i++)  

  116.    {  

  117. for(j = 0; j < b.len; j++)  

  118.        {  

  119.            c.num[i+j] += (a.num[i]*b.num[j]);  

  120. if(c.num[i+j] >= 10)  

  121.            {  

  122.                c.num[i+j+1] += c.num[i+j]/10;  

  123.                c.num[i+j] %= 10;  

  124.            }  

  125.        }  

  126.    }  

  127.    len = a.len+b.len-1;  

  128. while(c.num[len-1] == 0 && len > 1)  

  129.        len--;  

  130. if(c.num[len])  

  131.        len++;  

  132.    c.len = len;  

  133. return  c;  

  134. }  

  135. //高精度除以低精度,除的结果为c, 余数为f

  136. void Div1(BigNum &a, int &b, BigNum &c, int &f)  

  137. {  

  138. int  i, len = a.len;  

  139.    memset(c.num, 0, sizeof(c.num));  

  140.    f = 0;  

  141. for(i = a.len-1; i >= 0; i--)  

  142.    {  

  143.        f = f*10+a.num[i];  

  144.        c.num[i] = f/b;  

  145.        f %= b;  

  146.    }  

  147. while(len > 1 && c.num[len-1] == 0)  

  148.        len--;  

  149.    c.len = len;  

  150. }  

  151. //高精度*10

  152. void  Mul10(BigNum &a)  

  153. {  

  154. int  i, len = a.len;  

  155. for(i = len; i >= 1; i--)  

  156.        a.num[i] = a.num[i-1];  

  157.    a.num[i] = 0;  

  158.    len++;  

  159. //if a == 0

  160. while(len > 1 && a.num[len-1] == 0)  

  161.        len--;  

  162. }  

  163. //高精度除以高精度,除的结果为c,余数为f

  164. void Div2(BigNum &a, BigNum &b, BigNum &c, BigNum &f)  

  165. {  

  166. int  i, len = a.len;  

  167.    memset(c.num, 0, sizeof(c.num));  

  168.    memset(f.num, 0, sizeof(f.num));  

  169.    f.len = 1;  

  170. for(i = len-1;i >= 0;i--)  

  171.    {  

  172.        Mul10(f);  

  173. //余数每次乘10

  174.        f.num[0] = a.num[i];  

  175. //然后余数加上下一位

  176. ///利用减法替换除法

  177. while(Comp(f, b) >= 0)  

  178.        {  

  179.            f = Sub(f, b);  

  180.            c.num[i]++;  

  181.        }  

  182.    }  

  183. while(len > 1 && c.num[len-1] == 0)  

  184.        len--;  

  185.    c.len = len;  

  186. }  

  187. void  print(BigNum &a)   //输出大数

  188. {  

  189. int  i;  

  190. for(i = a.len-1; i >= 0; i--)  

  191.        printf("%d", a.num[i]);  

  192.    puts("");  

  193. }  

  194. //将字符串转为大数存在BigNum结构体里面

  195. BigNum ToNum(char *s)  

  196. {  

  197. int i, j;  

  198.    BigNum  a;  

  199.    a.len = strlen(s);  

  200. for(i = 0, j = a.len-1; s[i] != '\0'; i++, j--)  

  201.        a.num[i] = s[j]-'0';  

  202. return  a;  

  203. }  

  204. void Init(BigNum &a, char *s, int &tag)   //将字符串转化为大数

  205. {  

  206. int  i = 0, j = strlen(s);  

  207. if(s[0] == '-')  

  208.    {  

  209.        j--;  

  210.        i++;  

  211.        tag *= -1;  

  212.    }  

  213.    a.len = j;  

  214. for(; s[i] != '\0'; i++, j--)  

  215.        a.num[j-1] = s[i]-'0';  

  216. }  

  217. int main()  

  218. {  

  219.    BigNum a, b;  

  220. char  s1[100], s2[100];  

  221. while(scanf("%s %s", s1, s2) != EOF)  

  222.    {  

  223. int tag = 1;  

  224.        Init(a, s1, tag);    //将字符串转化为大数

  225.        Init(b, s2, tag);  

  226.        a = Add(a, b);  

  227. if(a.len == 1 && a.num[0] == 0)  

  228.        {  

  229.            puts("0");  

  230.        }  

  231. else

  232.        {  

  233. if(tag < 0) putchar('-');  

  234.            print(a);  

  235.        }  

  236.    }  

  237. return 0;  

  238. }