UVa 465 Overflow——WA

上次那个大数开方的高精度的题,UVa113 Power of Cryptography,直接两个double变量,然后pow(x, 1 / n)就A过去了。

怎么感觉UVa上高精度的题测试数据不给力啊。。。

话说回来,我写了100+行代码,WA了,后来考虑到要忽略前导0,又WA了,实在不知道哪出问题了。

 

 Overflow 

 

Write a program that reads an expression consisting of twonon-negative integer and an operator. Determine if either integer or the resultof the expression is too large to be represented as a ``normal'' signed integer(type integer if you areworking Pascal, type int if you areworking in C).

Input

An unspecified number of lines. Each line will contain an integer,one of the two operators + or *, and another integer.

Output

For each line of input, print the input followed by 0-3 lines containingas many of these three messages as are appropriate: ``first number too big'',``second number too big'',``result too big''.

Sample Input

300 + 3
9999999999999999999999 + 11

Sample Output

300 + 3
9999999999999999999999 + 11
first number too big
result too big

 

看到好多人用atof(),就是把一个字符串转化成double型数据。

下面是百科内容:

 

表头文件 #include <stdlib.h>
定义函数 double atof(const char *nptr);
函数说明 atof()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时('\0')才结束转换,并将结果返回。参数nptr字符串可包含正负号、小数点或E(e)来表示指数部分,如123.456或123e-2。
返回值 返回转换后的浮点型数。
附加说明 atof()与使用strtod(nptr,(char**)NULL)结果相同。

 

 

如果用double的话,直接将数据和2^31-1进行比较判断是否溢出就好了。

这是别人的AC代码。

 1 //#define LOCAL
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cstdlib>
 6 using namespace std;
 7 
 8 const int INT = 2147483647;
 9 const int maxn = 300;
10 char a[maxn], b[maxn], c;
11 
12 int main(void)
13 {
14     #ifdef LOCAL
15         freopen("465in.txt", "r", stdin);
16     #endif
17 
18     double x, y, z;
19     while(scanf("%s %c %s", a, &c, b) == 3)
20     {
21         printf("%s %c %s\n", a, c, b);
22         x = atof(a);
23         y = atof(b);
24         if(c == '+')
25             z = x + y;
26         if(c == '*')
27             z = x * y;
28         if(x > INT)
29             cout << "first number too big" << endl;
30         if(y > INT)
31             cout << "second number too big" << endl;
32         if(z > INT)
33             cout << "result too big" << endl;
34     }
35     return 0;
36 }
代码君

可我还是想把自己WA的代码贴出来,毕竟是花了大心思用心去写的。

而且这个代码也通过了样例测试和我自己能想到的各种极端的情况。

  1 //#define LOCAL
  2 #include <iostream>
  3 #include <cstdio>
  4 #include <cstring>
  5 using namespace std;
  6 
  7 const int maxn = 300;
  8 const char *INT = "2147483647";
  9 char a[maxn], b[maxn], c[maxn], result[maxn];
 10 int x[maxn], y[maxn], z[maxn];
 11 bool judge(char c[], int l);
 12 void fun(char c[]);
 13 
 14 int main(void)
 15 {
 16     #ifdef LOCAL
 17         freopen("465in.txt", "r", stdin);
 18     #endif
 19 
 20     char op;
 21     while(gets(c))
 22     {
 23         cout << c << endl;
 24         sscanf(c, "%s %c %s", a, &op, b);
 25         fun(a);
 26         fun(b);
 27         int la = strlen(a);
 28         int lb = strlen(b);
 29         bool flaga, flagb;
 30         if(flaga = judge(a, la))
 31             cout << "first number too big" << endl;
 32         if(flagb = judge(b, lb))
 33             cout << "second number too big" << endl;
 34 
 35         int i, j;
 36         //对结果是否溢出进行处理
 37         if(op == '+')
 38         {
 39             if(flaga || flagb)//加法运算有一个加数溢出那么结果溢出
 40             {
 41                 cout << "result too big" << endl;
 42                 continue;
 43             }
 44             memset(x, 0, sizeof(x));
 45             memset(y, 0, sizeof(y));
 46             for(i = la - 1; i >= 0; --i)
 47                 x[la - 1 - i] = a[i] - '0';
 48             for(i = lb - 1; i >= 0; --i)
 49                 y[lb - 1 - i] = b[i] - '0';
 50             for(i = 0; i < lb; ++i)//高精度加法运算
 51             {
 52                 x[i] = x[i] + y[i];
 53                 if(x[i] > 10)
 54                 {
 55                     j = i;
 56                     while(x[j] > 10)//处理连续进位的问题
 57                     {
 58                         x[j++] -= 10;
 59                         ++x[j];
 60                     }
 61                 }
 62             }
 63         }
 64 
 65         if(op == '*')
 66         {
 67             //如果乘数为0的话,那么结果不溢出
 68             if((la == 1 && a[0] == '0') || (lb == 1 && b[0] == '0'))
 69                 continue;
 70             else
 71             {
 72                 if((flaga || flagb) || (la + lb > 11))//有一个乘数溢出或者两乘数位数之和超过11位
 73                 {
 74                     cout << "result too big" << endl;
 75                     continue;
 76                 }
 77                 memset(x, 0, sizeof(x));
 78                 memset(y, 0, sizeof(y));
 79                 for(i = la - 1; i >= 0; --i)
 80                     x[la - 1 - i] = a[i] - '0';
 81                 for(i = lb - 1; i >= 0; --i)
 82                     y[lb - 1 - i] = b[i] - '0';
 83 
 84                 for(i = 0; i < lb; ++i)
 85                 {
 86                     int s = 0, c = 0;
 87                     for(j = 0; j < maxn; ++j)
 88                     {
 89                         s = x[j] * y[i] + c;
 90                         x[i + j] = s % 10;
 91                         c = s / 10;
 92                     }
 93                 }
 94             }
 95         }
 96 
 97         for(i = maxn - 1; i >= 0; --i)
 98             if(x[i] != 0)
 99                 break;
100         memset(result, 0, sizeof(result));
101         j = 0;
102         for(; i >= 0; --i)
103             result[j++] = x[i] + '0';//将结果转化为字符串好进行判断
104         if(judge(result, strlen(result)))
105             cout << "result too big" << endl;
106     }
107     return 0;
108 }
109 //判断一个字符串是否会溢出
110 bool judge(char c[], int l)
111 {
112     if(l > 10)
113         return true;
114     if(l < 10)
115         return false;
116     if(strcmp(c, INT) > 0)
117         return true;
118     return false;
119 }
120 //忽略字符串的前导0
121 void fun(char c[])
122 {
123     if(c[0] != '0')
124         return;
125     int i = 0, j = 0;
126     while(c[i] == '0')
127         ++i;
128     for(; c[i] != '\0'; ++i)
129         c[j++] = c[i];
130     c[j] = '\0';
131 }
代码君

 

posted @ 2014-07-01 08:27  AOQNRMGYXLMV  阅读(189)  评论(0编辑  收藏  举报