洛谷 P1055 ISBN 号码 题解
2026-09-20 22:13:10
发布于:浙江
1阅读
0回复
0点赞
题目描述
每一本正式出版的图书都有一个 ISBN 号码,格式形如 x-xxx-xxxxx-x。
最后一位是识别码,需要根据前 9 位数字计算得到。
计算规则:
- 前 9 位数字从左到右分别乘以
1, 2, 3, ..., 9; - 将乘积求和,对
11取模; - 若余数为
10,识别码为X,否则识别码就是该余数。
给定一个 ISBN 号码,判断其识别码是否正确:
- 正确输出
Right; - 错误则输出修正后的 ISBN 号码。
输入说明
本题输入格式固定为 x-xxx-xxxxx-x,共 13 个字符,且不包含空格。
因此可以直接使用:
string s;
cin >> s;
一次性读入整个 ISBN 串,而不是用循环逐字符 cin >> a[i]。
cin >> s 会从第一个非空白字符开始读取,直到遇到空白字符为止,正好读入完整的 ISBN 号码。
由于题目保证输入格式合法,我们不需要:
- 检查字符串长度是否为 13;
- 验证
-是否出现在固定位置; - 处理非法字符或格式错误。
直接按下标访问即可:s[0] 到 s[12] 对应 ISBN 的 13 个字符,其中 s[1]、s[5]、s[11] 是分隔符 -。
思路
遍历前 12 个字符,跳过 -,把其中的数字依次乘以 1 到 9 并累加。
得到总和 sum 后,计算 sum % 11:
- 若结果为
10,正确识别码是'X'; - 否则正确识别码是
'0' + (sum % 11)。
最后将计算出的识别码与 s[12] 比较:
- 相同:输出
Right; - 不同:把
s[12]替换为正确识别码,输出整个字符串。
代码实现(C++)
#include <iostream>
#include <string>
using namespace std;
int main() {
string s;
cin >> s; // 一次性读入整个 ISBN 串
int sum = 0, w = 1;
// 遍历前 12 个字符,跳过 '-'
for (int i = 0; i < 12; i++) {
if (s[i] != '-') {
sum += (s[i] - '0') * w;
w++;
}
}
// 计算正确的识别码
char check;
int mod = sum % 11;
if (mod == 10) {
check = 'X';
} else {
check = char('0' + mod);
}
// 判断并输出
if (s[12] == check) {
cout << "Right" << endl;
} else {
s[12] = check;
cout << s << endl;
}
return 0;
}
注意事项
- 输入读取:使用
cin >> s一次性读入整个 ISBN 串,因为输入无空格,且格式固定。 - 无需校验:题目保证输入合法,不需要检查长度、分隔符位置或字符范围。
- 跳过分隔符:前 12 位中有 3 个
-,它们不参与计算。 - 权重从 1 开始:第 1 个数字乘 1,第 2 个数字乘 2,……,第 9 个数字乘 9。
- 余数为 10 时输出
X:注意是大写字母X,不是数字 10。 - 字符与数字的转换:
s[i] - '0'可以把字符数字转成整数。 - 输出格式:若错误,输出完整的 13 位 ISBN 号码,不要漏掉分隔符。
复杂度分析
- 时间复杂度:
O(1),字符串长度固定为 13。 - 空间复杂度:
O(1),只用到了常数个变量。
这样就能顺利通过本题啦!🎉马鹿野郎!
这里空空如也

有帮助,赞一个