回文数题解

news/2024/10/12 3:50:41/

说明

若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。
例如:给定一个10进制数56,将56加56(即把56从右向左读),得到121是一个回文数。
又如:对于10进制数87:
    STEP1:87+78  = 165                    STEP2:165+561 = 726
    STEP3:726+627 = 1353                STEP4:1353+3531 = 4884

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

输入格式

每个测试文件只包含一组测试数据,每组输入一个N(2<=N<=10,N=16)进制数M,每组的第一行输入N,第二行输入M。

输出格式

对于每组输入数据,输出最少经过几步可以得到回文数。如果在30步以内(包含30步)不可能得到回文数,则输出"Impossible!"。

样例

9
87
STEP=6

 c语言版:

#include <stdio.h>
#include <string.h>#define MAX 5000 // 定义字符数组的最大长度int len, d, lim = 30; // len表示字符串长度,d表示进制,lim表示最多进行30次操作
char str[MAX], rts[MAX]; // str用于存储原始字符串,rts用于存储反转后的字符串// 将字符串b反转,并存入字符串a中
void fz(char a[MAX], char b[MAX]) {// 从b的末尾依次赋值到a的前面,实现反转for (int i = 0; i < len; ++i) {a[i] = b[len - 1 - i];}a[len] = '\0'; // 确保字符串末尾是'\0'结束符
}// 实现字符串str和rts的按进制d的加法,并存入rts
void add() {int carry = 0; // carry用于存储进位for (int i = 0; i < len; ++i) {// 将str和rts对应位相加,并加上进位carryrts[i] += str[i] - '0' + carry;carry = (rts[i] - '0') / d; // 计算进位值rts[i] = (rts[i] - '0') % d + '0'; // 当前位取模,重新变成字符}// 如果有进位,处理进位部分if (carry) {rts[len] = '0' + carry;rts[++len] = '\0'; // 增加新的一位,并确保字符串以'\0'结尾}
}// 判断当前字符串rts是否为回文
int judge() {// 从两端向中间逐位比较字符for (int i = 0; i < len; ++i) {if (rts[i] != rts[len - 1 - i]) {return 0; // 如果存在不相等的字符,返回0表示不是回文}}return 1; // 如果所有字符都相等,返回1表示是回文
}int main() {// 输入进制d和字符串strscanf("%d %s", &d, str);// 将输入字符串中的大写字母转换为相应的数字for (int i = 0; i < strlen(str); ++i) {if ('A' <= str[i] && str[i] <= 'Z') {str[i] = str[i] - 'A' + '9' + 1; // 将'A'-'Z' 转换为 10-35}}// 最多进行lim(30次)的操作,寻找回文数for (int i = 0; i <= lim; ++i) {len = strlen(str); // 获取当前字符串长度fz(rts, str); // 将str反转存入rts中// 判断rts是否为回文,如果是则退出循环if (judge()) {printf("STEP=%d\n", i); // 输出找到回文的步骤数return 0;}// 如果不是回文,则将str和rts相加,并存入rts中add();fz(str, rts); // 将rts反转后重新存入str,进行下一次循环}// 如果超过30次仍然没有找到回文,则输出"Impossible!"printf("Impossible!\n");return 0;
}

解释:

  1. 主函数

    • 输入进制 d 和字符串 str
    • 将输入字符串中的大写字母转换为对应的数字(A 转换为 10,B 转换为 11,依次类推)。
    • 循环最多进行 lim 次操作,每次检查是否为回文,如果是回文则输出操作步数 STEP=n,如果超过 lim 次仍未找到回文则输出 Impossible!
C 语言版本的关键点:
  • C 语言中数组操作需要手动管理字符数组的末尾 \0,这是与 C++ 中 string 的区别之一。
  • 输入与输出使用 scanfprintf,比 C++ 更为低级,但更加高效

C++ 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vll;
typedef pair<int,int> pii;
#define endl '\n'
const ll MAXN = 2e5+10; // 定义最大数组长度
char letter[20] = "0123456789ABCDEF"; // 进制表示用到的字符表// 将字符转换为数字的函数
int char_to_int(char c) {// 如果是数字字符(0-9),则返回数字本身;如果是字母(A-F),则返回对应的数值return isdigit(c) ? c - '0' : c - 'A' + 10;
}// 将数字转换为字符的函数
char int_to_char(int n) {// 返回数字对应的进制字符return letter[n];
}// 反转字符串并进行两数相加的函数,返回相加后的字符串
string radd(string a, int k) {string b = a; reverse(b.begin(), b.end()); // 将字符串 a 反转,存储到 b 中string ans; // 用于存储最终的结果字符串vector<int> nums(a.length() + 1, 0); // 动态分配数组用于存储每一位的加和结果,并初始化为 0int aL = a.length(); // 获取字符串 a 的长度// 将字符转换为数字并进行对应位置的加法for (int i = 0; i < aL; i++) {int numa = char_to_int(a[i]); // 将 a[i] 转换为相应的数值int numb = char_to_int(b[i]); // 将 b[i] 转换为相应的数值nums[i] += numa + numb; // 对应位的两个数字相加}// 处理进位for (int i = 0; i < aL; i++) {if (nums[i] >= k) { // 如果当前位大于等于进制 k,则需要进位nums[i+1] += nums[i] / k; // 进位给下一位nums[i] %= k; // 当前位保留进制范围内的值}}if (nums[aL]) aL++;  // 如果最后有进位,则需要增加长度// 将结果转换回字符串for (int i = aL - 1; i >= 0; i--) {ans += int_to_char(nums[i]); // 将数字转换为字符并拼接到结果字符串中}return ans; // 返回相加后的字符串
}int main() {ios_base::sync_with_stdio(false); // 提高输入输出效率,关闭 C 风格的同步cin.tie(nullptr); // 取消 cin 和 cout 的绑定,进一步提升性能string M; // 用于存储输入的数字字符串int N, cnt = 1; // N 表示输入的进制,cnt 表示步骤计数,初始化为 1cin >> N >> M; // 输入进制 N 和数字字符串 Mstring temp = radd(M, N), s; // 调用 radd 函数将 M 和它的反转相加,存储到 temp 中s = temp; reverse(s.begin(), s.end()); // 将 temp 反转,存储到 s 中// 循环直到找到回文数或者超过 30 步while (temp != s) { // 当 temp 不是回文时cnt++; // 步骤计数器加 1if (cnt > 30) { // 如果步骤超过 30,则输出 "Impossible!"cout << "Impossible!" << endl;return 0; // 程序结束}temp = radd(temp, N); // 将当前字符串 temp 与它的反转相加s = temp; reverse(s.begin(), s.end()); // 将新的 temp 再次反转}// 如果找到回文数,输出步骤数cout << "STEP=" << cnt << endl;return 0; // 程序结束
}
#include<iostream>
#include<string.h>
using namespace std;const int Max = 5000; // 最大字符数组大小
int len, d, lim = 30; // len表示字符串长度,d表示进制,lim表示最多进行30次操作
char str[Max], rts[Max]; // str是原始字符串,rts是反转后的字符串// 将字符串b反转并存入字符串a中
void fz(char a[Max], char b[Max]) {// 遍历字符串b,将b的字符从末尾依次复制到a的前面,达到反转的效果for (int i = 0; i < len; ++i)a[i] = b[len - 1 - i];
}// 实现str和rts的加法,并存回rts中,按指定进制d进行进位
void add() {int c = 0; // 用于保存进位// 从低位开始将str和rts对应位置的数字相加for (int i = 0; i < len; ++i) {rts[i] += str[i] - '0' + c; // 当前位的相加结果存入rts[i]c = (rts[i] - '0') / d; // 计算进位,当前位的值除以进制drts[i] = (rts[i] - '0') % d + '0'; // 当前位的值取模进制d,并转回字符}// 如果最高位仍然有进位,则将进位存入rts的下一位if (c) rts[len] = '0' + c;
}// 判断当前字符串rts是否为回文
bool judge() {// 从两端开始向中间逐位比较,如果有不相等的字符则返回falsefor (int i = 0; i < len; ++i)if (rts[i] != rts[len - 1 - i]) return false;// 如果所有字符都相等,则返回true,表示是回文return true;
}int main() {// 输入进制d和字符串strcin >> d >> str;// 将输入字符串中的大写字母转换为对应的数字// 比如'A' 转换为 10,'B' 转换为 11,依次类推int i;for (i = 0; i < strlen(str); ++i) {if ('A' <= str[i] && str[i] <= 'Z') str[i] = str[i] - 'A' + '9' + 1; // 大写字母转换为数字字符}// 最多进行lim(即30)次的加法反转判断操作for (i = 0; i <= lim; ++i) {len = strlen(str); // 计算当前字符串长度fz(rts, str); // 将str反转并存入rts// 判断rts是否为回文字符串,如果是则退出循环if (judge() == true) break;add(); // 如果不是回文,则将str和rts相加,并将结果存入rts中len = strlen(rts); // 更新rts的长度// 将rts再反转存入str,继续下一轮循环fz(str, rts);}// 输出结果,如果在30步以内找到回文,则输出步骤数if (i <= lim) cout << "STEP=" << i << endl;// 如果超过30步仍未找到回文,则输出"Impossible!"else cout << "Impossible!" << endl;
}

 

 


http://www.ppmy.cn/news/1537752.html

相关文章

selenium:Select类操作复选框和下拉框(7)

复选框/下拉框操作的Select类 主要使用selinium中的类Select来模拟选择网页上的下拉框或者复选框中的内容&#xff0c;使用前先导入 from selenium.webdriver.support.ui import Select 主要方法如下&#xff1a; 函数 功能 select_by_value 根据复选框/下拉框的值选择 se…

【react】开发常用hooks统计

最近一段时间一直开发react&#xff0c;虽然对框架层面没什么大的见解&#xff0c;但是对hooks的使用增多&#xff0c;这里记录一下常用hooks以便查阅。 因为接触react的时候&#xff0c;react已经出到18了&#xff0c;本文主要以函数式组件 react hooks来进行记录&#xff08…

卸载PLSQL及标准卸载流程

目录 1. 卸载PLSQL2. 删除注册表3. 删除数据信息 1. 卸载PLSQL 等待进度条走完 2. 删除注册表 regedit 右击删除 3. 删除数据信息 由于AppData是隐藏文件&#xff0c;需要勾选隐藏的项目。 重启电脑&#xff0c;PLSQL就卸载成功了。

零基础多图详解图神经网络(GNN/GCN)【李沐论文精读】

A Gentle Introduction to Graph Neural Networks 在上图中&#xff0c;每一层都是一层网络&#xff0c;每一层的节点都受到下一层中自身节点和邻居节点的影响。如果网络比较深&#xff0c;是可以处理到一幅图中较大范围的节点。 前言 图神经网络在应用上还只是起步阶段&…

QT学习笔记2.1(安装部署_QT Creator安装)

QT学习笔记2.1&#xff08;QT Creator安装&#xff09; 我目前主要使用msvc进行编译运行。 Qt Creator 的下载与安装 - wenglabs - 博客园 Qt - Qt Creator下载与安装 - [BORUTO] - 博客园 Qt 添加MSVC2017编译器&#xff08;2022年保姆级教程&#xff0c;不安装完整VS&#x…

机器学习框架总结

机器学习框架是用于构建、训练、评估和部署机器学习模型的工具和库的集合。它们简化了模型开发过程&#xff0c;并提供了预构建的功能、优化的计算性能和对深度学习、监督学习、无监督学习等技术的支持。下面是一些主要的机器学习框架的详细介绍&#xff1a; 1. TensorFlow 1…

八大排序--07归并排序

假设数组 arr[] {5,7,4,2,0,1,6},请通过插入排序的方式&#xff0c;实现从小到大排列&#xff1a; 方法&#xff1a;先拆分&#xff0c;再合并&#xff0c;并在合并过程中结束临时空间进行排序&#xff1b; 拆分&#xff1a;从待排序列中间位置拆开&#xff0c;数据分成左右两…

bclinux安装minio和mc及从服务器上下载文件

下载MinIO服务器二进制文件 访问MinIO的官方网站或使用wget、curl等工具直接从MinIO的官方GitHub存储库下载最新版本的MinIO服务器二进制文件。例如&#xff0c;使用以下命令&#xff1a; 下载命令&#xff1a;wget https://dl.min.io/server/minio/release/linux-amd64/ 授…