zzulioj - 2599: 对称的数字

题目链接:

http://acm.zzuli.edu.cn/problem.php?id=2599

题目描述
小D同学发现了一些数字与其反转数字相加求和得出新数字,新数字再不断重复这个过程,最终可能得到一个回文数,当然啦也有些数字不断重复这个过程也得不到回文数。例如数字349,有如下过程

349 + 943 = 1292 

1292 + 2921 = 4213

4213 + 3124 = 7337 

也就是经过3次迭代得到了了一个回文数。现在小D同学给你一个数字,问你能不能在1到100次迭代内(包含100次)得到一个回文数,如果可以输出这个回文数,如果不可以则输出NO。

输入
多组测试数组,以EOF结束。
每组测试数据一行,每行一个整数,表示小D同学给出的数字,给出的整数大于等于0且在int范围内
输出
每个测试数据输出一行,如果可以在1到100次迭代(包含100次)内得到回文数,那么输出这个回文数,如果不可以,则输出NO
样例输入  Copy
349
6580
101
样例输出  Copy
7337
NO
202

这个题表面上看起来很简单....但是如果直接写的话就算用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;
}
 

猜你喜欢

转载自www.cnblogs.com/shuitiangong/p/12070240.html
今日推荐