1

题目大意:

定义种操作:让一个条数加上这个整数首尾颠倒后的数字。例如对整数1257执行操作就是1257 + 7521 = 8778.* 现在给出一个正整数和操作次数限制,问在限定的操作次数内能是否能得到回文数。如果能得到,则输出那个回文数,并输出操作的次数;否则,输出最后一次操作得到的数字以及操作次数。

算法思路:

此题的数据范围有可能会超过long long类型(本人没有测试),并且这里涉及到了逆置操作,使用字符串才处理该数字较为方便,这个问题的关键两个问题就是如何判断一个数字是回文数,第二个就是如何实现2个字符串或者大整数的加法操作。第一个问题只需要判断字符串中对称位置的字符是否相等即可(对称位置的和为字符串长度),第二个问题在这里也比较好处理,因为第二个整数是第一个整数逆置得到的,所以这两个整数的长度是相同的,那么就只需要使用指针i从后往前扫描每一位,然后计算对应的部分和partialSum = (s1[i]-'0')+(s2[i]-'0')+carry;这里使用carry保存上一位的进位,初始为0,然后计算进位carry = partialSum/10;并且使用字符串r保存相加后的本位数字partialSum%10,最后得注意如果最高位有进位得添加进位到r中。

算法流程:

使用step记录执行加法的次数,初始为0,然后只要step<K那么就进入循环,如果当前数字N为回文数字,就退出循环进行输出操作,否则就使用s保存N的逆置数,将N和s相加的结果保存到N中,并step自增。最后在循环退出的时候输出结果和执行次数。

提交结果:

image.png

AC代码:

#include <cstdio>
#include <string>
#include <iostream>
#include <algorithm>

using namespace std;

bool isPalindromic(string s){
    for (int i = 0; i < s.size() / 2; ++i) {
        if(s[i]!=s[s.size()-i-1]){
            return false;
        }
    }
    return true;
}

string add(string s1,string s2){
    int carry = 0;
    int partialSum = 0;
    string r;
    for (int i = s1.size()-1; i >= 0; --i) {// s1和s2实际是一样长的
        partialSum = (s1[i]-'0')+(s2[i]-'0')+carry;
        carry = partialSum/10;
        r += to_string(partialSum%10);
    }
    // 由于s1和s2是一样长的,就无需判断s1或者s2还有部分需要相加了。
    if(carry!=0){
        r += to_string(carry);
    }
    reverse(r.begin(),r.end());
    return r;
}

int main(){
    string N;
    cin>>N;
    int K;
    scanf("%d",&K);
    int step = 0;
    string s;
    while (step<K){
        if(isPalindromic(N)) break;
        s = N;
        reverse(s.begin(),s.end());
        N = add(N,s);
        ++step;
    }
    printf("%s\n%d",N.c_str(),step);
    return 0;
}

乔梓鑫
569 声望17 粉丝

主要分享个人学习经验和心得