zzulioj - 2599: 对称的数字(高精度加法)
题目链接:
http://acm.zzuli.edu.cn/problem.php?id=2599
这个题表面上看起来很简单....但是如果直接写的话就算用long long也会有越界的情况(double即使不越界,也可能有精度损失)所以我们需要用到大整数加法
#include<set> #include<map> #include<stack> #include<queue> #include<cmath> #include<cstdio> #include<cctype> #include<string> #include<vector> #include<climits> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define max(a, b) (a > b ? a : b) #define min(a, b) (a < b ? a : b) #define mst(a) memset(a, 0, sizeof(a)) #define _test printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n") using namespace std; typedef long long ll; typedef pair<int, int> P; const double eps = 1e-7; const int INF = 0x3f3f3f3f; const ll ll_INF = 233333333333333; const int maxn = 1e3+10; char num1[maxn], num2[maxn], res[maxn]; void sum() { //大整数加法 mst(res); int len1 = strlen(num1); int len2 = strlen(num2); reverse(num1, num1+len1); //反转第一个数 reverse(num2, num2+len2); //反转第二个数 int kase = 0; while(kase < len1 && kase < len2) { //重叠部分相加 res[kase+1] = (res[kase] + num1[kase] + num2[kase] - '0'*2)/10; //模拟进位相加 res[kase] = (res[kase] + (num1[kase] + num2[kase] - '0'*2))%10 + '0'; ++kase; } while(kase < len1) { //非重叠部分相加 res[kase+1] = (res[kase] + num1[kase] - '0')/10; res[kase] = (res[kase] + num1[kase] - '0')%10 + '0'; ++kase; } while(kase < len2) { //同上 res[kase+1] = (res[kase] + num2[kase] - '0')/10; res[kase] = (res[kase] + num2[kase] - '0')%10 + '0'; ++kase; } if (res[kase]) { //判断最后一次相加有没有进位 res[kase] += '0'; res[++kase] = '\0'; } else res[kase] = '\0'; } bool okk() { //判断回文 int len = strlen(res); for (int i = 0; i<len/2; ++i) if (res[i] != res[len-i-1]) return false; return true; } int main(void) { while(~scanf("%[^\n]%*c", num1)) { bool ok = false; strcpy(num2, num1); for (int i = 0; i<100; ++i) { reverse(num2, num2+strlen(num2)); sum(); //将反转过后的数与原数字相加 if (okk()) { //判断是否满足回文 ok = true; break; } strcpy(num1, res); //将相加后的结果复制给另外两个数字准备下次计算 strcpy(num2, res); } printf(ok ? "%s\n" : "NO\n", res); } return 0; }