[NOIP1999 普及组] 回文数

题目描述

若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。

例如:给定一个十进制数 56,将 56 加 65(即把 56 从右向左读),得到 121 是一个回文数。

又如:对于十进制数 87:

STEP1:87+78=165
STEP2:1165+561=726
STEP3:726+627=1353
STEP4:1353+3531=4884

在这里的一步是指进行了一次 N 进制的加法,上例最少用了 4 步得到回文数 4884。

写一个程序,给定一个 N(2≤N≤10 或 N=16)进制数 M(100 位之内),求最少经过几步可以得到回文数。如果在 30 步以内(包含 30 步)不可能得到回文数,则输出 Impossible!

输入格式

两行,分别是 N,M。

输出格式

如果能在 30 步以内得到回文数,输出格式形如 STEP=ans,其中ans 为最少得到回文数的步数。

否则输出 Impossible!

输入输出样例

输入 #1

10
87

输出 #1

STEP=4
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>

using namespace std;

// 判断一个字符串是否是回文数
bool isPalindrome(const string &s) {
    int left = 0, right = s.size() - 1; // 初始化左右指针
    while (left < right) { // 当左指针小于右指针时循环
        if (s[left] != s[right]) { // 如果左右指针指向的字符不相等
            return false; // 返回false,表示不是回文数
        }
        left++; // 左指针右移
        right--; // 右指针左移
    }
    return true; // 返回true,表示是回文数
}

// 将字符串表示的N进制数反转
string reverseString(const string &s) {
    string rev = s; // 复制原字符串
    reverse(rev.begin(), rev.end()); // 反转字符串
    return rev; // 返回反转后的字符串
}

// 将字符串表示的N进制数转换为整数
int charToDigit(char c) {
    if (c >= '0' && c <= '9') return c - '0'; // 如果是数字字符,返回对应的整数
    if (c >= 'A' && c <= 'F') return c - 'A' + 10; // 如果是字母字符,返回对应的整数
    return -1; // 错误情况
}

// 将整数转换为字符
char digitToChar(int d) {
    if (d >= 0 && d <= 9) return '0' + d; // 如果是0-9的整数,返回对应的字符
    if (d >= 10 && d <= 15) return 'A' + (d - 10); // 如果是10-15的整数,返回对应的字符
    return '0'; // 错误情况
}

// 进行N进制数的加法
string addInBaseN(const string &a, const string &b, int base) {
    string result; // 存储结果的字符串
    int carry = 0; // 进位初始化为0
    int i = a.size() - 1, j = b.size() - 1; // 初始化两个字符串的末尾索引
    while (i >= 0 || j >= 0 || carry) { // 当索引大于等于0或者进位不为0时循环
        int sum = carry; // 当前位的和初始化为进位
        if (i >= 0) sum += charToDigit(a[i--]); // 如果a的索引有效,加上a的当前位
        if (j >= 0) sum += charToDigit(b[j--]); // 如果b的索引有效,加上b的当前位
        carry = sum / base; // 计算新的进位
        result.push_back(digitToChar(sum % base)); // 将当前位的结果添加到结果字符串中
    }
    reverse(result.begin(), result.end()); // 反转结果字符串,使其正确排列
    return result; // 返回结果字符串
}

int main() {
    int N; // 进制数
    string M; // 输入的N进制数
    cin >> N >> M; // 读取输入

    for (int step = 1; step <= 30; ++step) { // 循环最多30次
        string reversedM = reverseString(M); // 反转M
        string sum = addInBaseN(M, reversedM, N); // 计算M和反转M的和
        if (isPalindrome(sum)) { // 如果和是回文数
            cout << "STEP=" << step << endl; // 输出步数
            return 0; // 结束程序
        }
        M = sum; // 更新M为新的和
    }

    cout << "Impossible!" << endl; // 如果在30步内没有找到回文数,输出Impossible!
    return 0; // 结束程序
}

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值