首页 > 代码库 > 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型数据。
下面是百科内容:
如果用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 }