首页 > 代码库 > UVa 465 Overflow——WA

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 LOCAL15         freopen("465in.txt", "r", stdin);16     #endif17 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 //忽略字符串的前导0121 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 }
代码君