枚举 1~300 每个数的平方,用短除法把平方写成 B 进制串判回文,是则输出原数和平方的 B 进制串。
OJ: roj
题目 ID: 2007
难度:入门
标签:枚举模拟进制转换回文python
创建: 2026-10-01 02:40
更新: 2026-10-06 09:26
题目描述
回文数是从左向右读和从右向左读都一样的数,例如 12321。给定一个进制 A、B……表示 10、11 等数码。
输入样例(B = 10),输出样例(共 12 行,每行形如 x repr_B(x^2),此处为节省篇幅合并为一行展示,实际输出每对占一行):
text
1 1 / 2 4 / 3 9 / 11 121 / 22 484 / 26 676
101 10201 / 111 12321 / 121 14641 / 202 40804 / 212 44944 / 264 69696思路
按定义枚举 A ~ J),再判断该串正读反读是否相同。是回文就同时把
参考代码
Python 版:
python
#!/usr/bin/env python3
# Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
# rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
# rainboy的学习导航网站: https://idx.roj.ac.cn
# create_at: 2026-10-01 02:40
# update_at: 2026-10-01 02:40
import sys
from collections.abc import Iterator
MAX_N = 300 # 题面要求枚举的范围 [1, 300],与进制 B 无关
DIGITS = "0123456789ABCDEFGHIJ" # 数码表:下标即权值,10~19 用 A~J 表示
def to_base(value: int, base: int) -> str:
"""把十进制正整数写成 base 进制串(最高位在前)。"""
digits = ""
while value:
digits = DIGITS[value % base] + digits # 余数从低位到高位产生,故前置拼接
value //= base
return digits
def palindrome_squares(base: int) -> Iterator[tuple[int, str]]:
"""产出 [1, MAX_N] 内所有「平方是回文数」的 (原数, 平方的 base 进制串)。"""
for x in range(1, MAX_N + 1):
square = to_base(x * x, base)
if square == square[::-1]: # 反转后相同即为回文
yield x, square
def solve() -> None:
base = int(sys.stdin.read())
out = [f"{to_base(x, base)} {square}" for x, square in palindrome_squares(base)]
print("\n".join(out))
if __name__ == "__main__":
solve()C++ 版(同一算法):
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-10-06 09:25
* update_at: 2026-10-06 09:25
*/
#include <cstdio>
#include <string>
typedef long long ll;
const ll MAX_N = 300; // 题面要求的枚举上界:1 <= x <= 300
ll base; // 输入的进制 B(2~20)
char buf[50]; // 临时存放一条 B 进制串,用于反转比较
// 把十进制非负整数 value 写成 base 进制串(最高位在前)。
// 10~19 的数码依次用 'A'~'J' 表示。
std::string to_base(ll value) {
std::string digits = "";
if (value == 0)
return "0";
while (value) {
int r = value % base; // 余数即当前最低位
char c;
if (r < 10)
c = '0' + r;
else
c = 'A' + r - 10; // 数码 10~19 记为 A~J
digits = c + digits; // 余数从低位到高位产生,故前置拼接保证高位在前
value /= base;
}
return digits;
}
// 判断字符串 s 是否为回文串。
bool is_palindrome(const std::string &s) {
ll i = 0, j = s.size() - 1;
while (i < j) {
if (s[i] != s[j])
return false;
i++;
j--;
}
return true;
}
int main() {
scanf("%lld", &base);
// 按 x 升序枚举,输出天然有序;回文条件加在平方上而不是 x 上
for (ll x = 1; x <= MAX_N; x++) {
std::string sq = to_base(x * x);
if (is_palindrome(sq))
printf("%s %s\n", to_base(x).c_str(), sq.c_str());
}
return 0;
}