本文分享的必刷题目是从蓝桥云课、洛谷、AcWing等知名刷题平台精心挑选而来,并结合各平台提供的算法标签和难度等级进行了系统分类。题目涵盖了从基础到进阶的多种算法和数据结构,旨在为不同阶段的编程学习者提供一条清晰、平稳的学习提升路径。
欢迎大家订阅我的专栏:算法题解:C++与Python实现!
附上汇总贴:算法竞赛备考冲刺必刷题(C++) | 汇总
【题目来源】
洛谷:P1015 [NOIP 1999 普及组] 回文数 - 洛谷
【题目描述】
若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数。
例如:给定一个十进制数 56 56 56,将 56 56 56 加 65 65 65(即把 56 56 56 从右向左读),得到 121 121 121 是一个回文数。
又如:对于十进制数 87 87 87:
STEP1:
87
+
78
=
165
87+78=165
87+78=165
STEP2:
165
+
561
=
726
165+561=726
165+561=726
STEP3:
726
+
627
=
1353
726+627=1353
726+627=1353
STEP4:
1353
+
3531
=
4884
1353+3531=4884
1353+3531=4884
在这里的一步是指进行了一次 N N N 进制的加法,上例最少用了 4 4 4 步得到回文数 4884 4884 4884。
写一个程序,给定一个
N
(
2
≤
N
≤
10
或
N
=
16
)
N(2≤N≤10 或 N=16)
N(2≤N≤10或N=16)进制数
M
M
M(
100
100
100 位之内),求最少经过几步可以得到回文数。如果在
30
30
30 步以内(包含
30
30
30 步)不可能得到回文数,则输出 Impossible!
。
【输入】
两行,分别是 N N N, M M M。
【输出】
如果能在
30
30
30 步以内得到回文数,输出格式形如 STEP=ans
,其中
a
n
s
ans
ans 为最少得到回文数的步数。
否则输出 Impossible!
。
【输入样例】
10
87
【输出样例】
STEP=4
【算法标签】
《洛谷 P1015 回文数》 #模拟# #高精度# #进制# #NOIP普及组# #1999#
【代码详解】
#include <bits/stdc++.h>
using namespace std;
// 定义大数结构体
struct Num
{
int num[200]; // 存储各位数字(逆序存储)
int len; // 数字长度
}a, b; // a: 原始数,b: 反转后的数
int n; // 进制数
string s; // 输入的字符串
// 反转数字
Num reverse(Num x)
{
Num res = {}; // 初始化结果
res.len = x.len;
// 将数字各位反转
for (int i = 0; i < res.len; i++)
res.num[i] = x.num[res.len - 1 - i];
return res;
}
// 判断两个数字是否相等
bool isEqual(Num x, Num y)
{
if (x.len != y.len)
return false;
// 逐位比较
for (int i = 0; i < x.len; i++)
if (x.num[i] != y.num[i])
return false;
return true;
}
// 大数加法(考虑进制)
Num add(Num x, Num y)
{
Num res = {}; // 初始化结果
res.len = x.len;
// 逐位相加
for (int i = 0; i < res.len; i++)
{
res.num[i] += x.num[i] + y.num[i]; // 当前位相加
res.num[i + 1] = res.num[i] / n; // 计算进位
res.num[i] %= n; // 计算当前位结果
}
// 处理最高位进位
if (res.num[res.len])
res.len++;
return res;
}
int main()
{
// 输入进制和数字字符串
cin >> n >> s;
// 将字符串转换为大数(逆序存储)
a.len = s.size();
for (int i = 0; i < a.len; i++)
{
// 处理字母和数字字符
if ('A' <= s[a.len - 1 - i] && s[a.len - 1 - i] <= 'Z')
a.num[i] = s[a.len - 1 - i] - 'A' + 10; // A-Z表示10-35
else
a.num[i] = s[a.len - 1 - i] - '0'; // 0-9直接转换
}
// 最多尝试30次
for (int i = 0; i <= 30; i++)
{
b = reverse(a); // 获取反转数
// 检查是否是回文数
if (isEqual(a, b))
{
cout << "STEP=" << i << endl;
return 0;
}
// 不是回文数则相加继续尝试
a = add(a, b);
}
// 超过30次仍未找到回文数
cout << "Impossible!" << endl;
return 0;
}
【运行结果】
10
87
STEP=4