1 solutions
-
0
[系统测试] A+B Problem ?
这个题确实和其他 OJ 常规签到的 A+B 不一样,需要考虑的点非常多。很快我们就看到了使用高精度以及
__int128_t
数据类型通过本题的同学们了。接下来给大家简单讲解一下各种做法都是怎么做的。1.常规做法
利用数组模拟高精度运算这个我们就不在这里做赘述了。这里只说使用
g++
和msvc
编译器都有的long long
以及unsigned long long
就能解决的做法。输入的整数 和 虽然在
long long
范围内,但是 就不一定了。Case 1
对于一正一负(或者至少一个是 0),必然不会爆
long long
的范围,所以我们照常输出 即可。Case 2
均为正数, 就有可能超过
long long
表示范围上限的 导致溢出,此时使用long long
运算就会输出一个负数。在这种情况下我们可以考虑用
unsigned long long
。因为两个最大为 的正数相加最大为 ,不会超出unsigned long long
的上限 ,因此直接强制类型转换计算即可。Case 3
均为负数,将两者取相反数,还用
unsigned long long
计算,计算结果多输出一个负数即可,这样可以应对一般的情况。Case 4
最后一组数据为 ,两者相加的结果为 ,这正好是
unsigned long long
无法存储的情况,因此直接特判并输出对应值 即可。#include <stdio.h> int main() { long long a, b; scanf("%lld %lld", &a, &b); // a + b 可能超过 long long 最大值 故用必正的 unsigned long long if (a >= 0 && b >= 0) { unsigned long long sum = a + b; printf("%llu\n", sum); } // 因为一正一非正 故相加不会超过long long范围正常输出即可 else if (((a > 0 && b <= 0)) || ((a <= 0) && (b > 0))) { long long sum = a + b; printf("%lld\n", sum); } // 特判 理由见上 else if (a == -9223372036854775808ll && b == -9223372036854775808ll) { printf("-18446744073709551616\n"); } // 因为特殊情况已经在上面被讨论 故剩下的可以放开手脚取相反数相加 else if (a <= 0 && b <= 0) { a = -a, b = -b; unsigned long long sum = a + b; printf("-%llu\n", sum); } return 0; }
2.
__int128_t
做法在 64 位架构的 g++ 编译器中,除了 8,16,32,64 位整数之外,还有 128 位整数
__int128_t
和__uint128_t
的存在(但是msvc
就无法使用了,因此也不建议大家用 Visual Studio 来刷题),数据表示范围对应进行了扩增。但是 128 位整数没有自带的输入/输出/哈希值等内容(也就意味着用 STL 存储 128 位整数时需要注意)。因此我们利用字符串处理的基础思想,使用
getchar
和putchar
输入输出即可。使用getchar
/putchar
的输入输出速度优于scanf
/printf
,此外还有fread
/fwrite
等更加快速的函数。我们会在其他的系统测试题目中为大家介绍。注意到 无法使用
putchar
进制转换的方式输出,因此也需要特判一下才能实现完整功能。但是对于本题自然是不需要的。#include <stdio.h> #include <ctype.h> typedef __int128_t i128; const i128 DINF128 = ((i128)(((long long)1) << 63)) << 64; i128 rd() { i128 k = 0, f = 1; char s = getchar(); while (!isdigit(s)) f = (s == '-') ? 0 : f, s = getchar(); while (isdigit(s)) k = (k << 1) + (k << 3) + (s ^ '0'), s = getchar(); return f ? k : -k; } void wr(i128 x) { if (x == DINF128) return (void)(puts("-170141183460469231731687303715884105728")); if (x < 0) x = -x, putchar('-'); if (x > 9) wr(x / 10); putchar((x % 10) ^ '0'); } int main() { wr(rd() + rd()); }
3.Python 做法
Python 的话和一般的 a+b 无异,原样输出即可。这是因为 Python 的
int
可以表示的范围非常大。但是除此之外,Python 在程序设计习题当中几乎没有其他优势。a, b = map(int, input().split()) print(a + b)
- 1
Information
- ID
- 1
- Time
- 1000ms
- Memory
- 512MiB
- Difficulty
- 1
- Tags
- # Submissions
- 59
- Accepted
- 11
- Uploaded By