按 ISBN-10 规则取前 9 位数字乘 1~9 求和后模 11,余 10 记为 X,与原识别码比较决定输出 Right 或补正后的完整 ISBN。
OJ: roj
题目 ID: 3560
难度:入门
标签:入门数学python
创建: 2026-10-02 07:36
更新: 2026-10-06 13:51
题目描述
ISBN 由 9 位数字、1 位识别码和 3 个分隔符组成,格式如 x-xxx-xxxxx-x;识别码算法是前 9 位数字依次乘 X。
输入一行格式合法的 ISBN 串;识别码正确输出 Right,否则输出补正后的完整 ISBN(保留 -)。样例:0-670-82162-4 输出 Right,0-670-82162-0 输出 0-670-82162-4。
思路
按定义模拟:去掉 - 后的前 9 位数字依次乘 X。与输入识别码相同输出 Right,否则输出前缀加正确识别码。
参考代码
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-07-05 21:47
# update_at: 2026-07-05 21:47
import sys
def check_digit(digits: str) -> str:
"""按 ISBN 规则算识别码:9 位依次乘 1..9 求和后 mod 11,余 10 记作 X。"""
remainder = sum(int(d) * w for d, w in zip(digits, range(1, 10))) % 11
return 'X' if remainder == 10 else str(remainder)
def solve() -> None:
# 题面保证 ISBN 串不含空白字符,整个输入就是唯一 token,按 next() 顺序消费
data = iter(sys.stdin.buffer.read().split())
isbn = next(data).decode()
body, given = isbn.rsplit('-', 1) # 拆出前 9 位(含两个 -)与识别码
digits = body.replace('-', '') # 只剩 9 位数字
correct = check_digit(digits)
if given == correct:
print('Right')
else:
print(f'{body}-{correct}')
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 13:51
* update_at: 2026-10-06 13:51
*/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
// isbn 保存输入的整个 ISBN 串,形如 0-670-82162-4
string isbn;
int main() {
cin >> isbn;
// 前 9 位数字(去掉 '-')依次乘 1..9 求和,再对 11 取余
ll weighted_sum = 0;
ll factor = 1;
ll len = isbn.size();
for (ll i = 0; i < len - 1; i++) {
if (isbn[i] == '-') {
continue;
}
weighted_sum += (isbn[i] - '0') * factor;
factor++;
}
ll remainder = weighted_sum % 11;
char correct; // 计算出的正确识别码,余 10 时记作 'X'
if (remainder == 10) {
correct = 'X';
} else {
correct = '0' + remainder;
}
if (isbn[len - 1] == correct) {
cout << "Right" << endl;
} else {
// 保留原前缀,替换最后一位识别码
for (ll i = 0; i < len - 1; i++) {
cout << isbn[i];
}
cout << correct << endl;
}
return 0;
}