当前位置: 首页 > web >正文

每日c/c++题 备战蓝桥杯(洛谷P1015 [NOIP 1999 普及组] 回文数)

洛谷P1015 [NOIP 1999 普及组] 回文数 题解

题目描述

P1015 回文数 是NOIP 1999普及组的经典模拟题。题目要求如下:

给定一个数N(十进制)和进制K(2≤K≤16),将N转换为K进制表示后,通过以下操作使其变为回文数:

  1. 将当前数与其逆序数相加
  2. 重复操作直到得到回文数或超过30次操作

输入格式

  • 第一行输入进制K(2≤K≤16)
  • 第二行输入十进制数N(1<N≤1e9)

输出格式

  • 若30步内得到回文数,输出STEP=步数
  • 否则输出Impossible!

解题思路

本题是典型的进制转换+模拟操作问题,核心在于:

  1. 正确实现大数的K进制转换
  2. 高效处理大数加法与进位
  3. 准确判断回文数

关键算法步骤

  1. 进制转换:将十进制数N转换为K进制表示
  2. 回文判断:检查当前数是否为回文
  3. 加法模拟:实现大数与其逆序数的加法运算
  4. 进位处理:处理不同进制下的进位逻辑

代码解析(附用户代码讲解)

以下是用户提供的代码的逐层解析:

#include<bits/stdc++.h>
#include<string>
using namespace std;int N;          // 目标进制
int step = 0;   // 操作步数
int len = 0;    // 当前数位长度
int ans[205] = {0};  // 存储K进制数(低位在前)
int tem[205] = {0};  // 临时反转数组
int re[205] = {0};   // 未使用(可忽略)// 回文数检查函数
int Check() {for(int i=0; i<len/2; ++i) {if(ans[i] != ans[len-i-1]) return -1;}return 1;
}// 加法操作函数
void play() {// 反转数组到temfor(int i=0; i<len; ++i) tem[i] = ans[len-i-1];// 执行加法for(int i=0; i<len; ++i) ans[i] += tem[i];// 进位处理for(int i=0; i<len; ++i) {if(N != 16) {  // 非16进制通用处理if(ans[len-1] >= N) len++;ans[i+1] += ans[i] / N;ans[i] %= N;} else {        // 16进制特殊处理if(ans[len-1] >= 16) len++;ans[i+1] += ans[i] / 16;ans[i] %= 16;}}
}int main() {ios::sync_with_stdio(false);cin.tie(0);string s;cin >> N >> s;len = s.length();// 初始化K进制数(注意低位存储方式)for(int i=0; i<len; ++i) {if(isdigit(s[len-i-1]))ans[i] = s[len-i-1] - '0';elseans[i] = s[len-i-1] - 'A' + 10;}if(Check() == 1) {  // 初始即为回文cout << "STEP=0";} else {while(step <= 30) {play();step++;if(Check() == 1) break;}if(step <= 30)cout << "STEP=" << step;elsecout << "Impossible!";}return 0;
}

代码特点分析

  1. 低位优先存储:使用数组ans[]的低位在前方式存储,简化进位操作
  2. 双模式进位处理:通过N != 16判断统一处理不同进制
  3. 动态长度维护:通过len变量动态跟踪当前数位长度

优化方案与注意事项

优化方向

  1. 预分配数组空间:可预先分配200位空间,避免频繁扩容
  2. 提前终止判断:在加法操作前即可判断是否已产生回文
  3. 进制处理统一化:将16进制特殊处理合并到通用逻辑中

关键细节说明

  1. 输入处理

    • 使用len-i-1实现字符串反转初始化
    • 正确处理字母A-F(10-15)的转换
  2. 进位逻辑

    • 从低位到高位处理进位
    • 每次加法后检查最高位是否需要扩容
  3. 回文判断

    • 只需检查前半部分与对应后半部分是否相等

测试样例分析

示例1

输入

9
87

输出

STEP=4

过程

87(10) = 106(9)
106 + 601 = 707(回文,4步)

示例2

输入

10
196

输出

Impossible!

(著名的回文数猜想反例)

复杂度分析

  • 时间复杂度:O(30*L),其中L为最大数位长度(≤200)
  • 空间复杂度:O(L),使用固定大小数组存储

总结

  1. 本题核心是掌握大数运算在模拟题中的应用
  2. 关键点在于:
    • 正确实现进制转换
    • 高效处理大数加法与进位
    • 准确判断回文结构
  3. 实际编程时需特别注意:
    • 数组越界问题(动态维护len变量)
    • 不同进制的字符处理(0-9和A-F)
    • 步骤计数器的初始值与终止条件

通过本题可以巩固:

  • 进制转换的双向实现
  • 大数运算的基本技巧
  • 模拟算法的优化策略
http://www.xdnf.cn/news/3789.html

相关文章:

  • 一些好玩的东西
  • [方法论]软件工程中的软件架构设计:从理论到实践的深度解析
  • 日本人工智能发展全景观察:从技术革新到社会重构的深度解析
  • Hive进阶之路
  • redis----通用命令
  • 探秘 RocketMQ 的 DLedgerServer:MemberState 的技术解析与深度剖析
  • Docker 服务搭建
  • 探秘 Git 底层原理:理解版本控制的基石
  • 计算方法实验六 数值积分
  • Docker安装Gitblit(图文教程)
  • TS typeof运算符
  • 深度学习学习笔记
  • 复刻低成本机械臂 SO-ARM100 标定篇
  • Granite 4.0 Tiny:IBM也开始卷大模型?
  • 234树和红黑树
  • 深入了解Linux系统—— 环境变量
  • 仓颉编程语言快速入门:从零构建全场景开发能力
  • 【Linux】命令行参数与环境变量
  • Spring MVC @CookieValue 注解怎么用?
  • 【前端】【面试】在 Vue-React 的迁移重构工作中,从状态管理角度来看,Vuex 迁移到 Redux 最大的挑战是什么,你是怎么应对的?
  • idea结合CopilotChat进行样式调整实践
  • 爬虫的应用
  • 测试基础笔记第十九天
  • CSS 变量与原生动态主题实现
  • 变更需求代价-影响分析过程
  • Hotspot分析(1):单细胞转录组识别信息基因(和基因模块)
  • 力扣面试150题--相同的树
  • windows鼠标按键自定义任意设置
  • 【中间件】brpc_基础_remote_task_queue
  • Oracle OCP认证考试考点详解083系列07