ISBN 号码
扫描 ISBN 的前九个数字计算带权和,再按模 11 规则校验或替换识别码。
OJ: shumeng
题目 ID: CSP201312B
难度:入门
标签:模拟
日期: 2026-07-31 16:21
形式化题目
输入格式正确的 ISBN 字符串 x-xxx-xxxxx-x,检查最后的识别码是否等于前九个数字按权重 X。
正确时输出 Right;错误时只替换最后一位,原样输出带连字符的正确 ISBN。
思路
先按题面固定位置取出九个数字,直接套用校验公式:
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-07-31 16:21
* update_at: 2026-08-17 22:45
*/
// brute.cpp:按 ISBN 固定格式逐位取出前 9 个数字,再直接套校验公式。
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
string isbn;
cin >> isbn;
int positions[9] = {0, 2, 3, 4, 6, 7, 8, 9, 10};
int sum = 0;
for (int i = 0; i < 9; i++) {
sum += (isbn[positions[i]] - '0') * (i + 1);
}
int remainder = sum % 11;
char correct = remainder == 10 ? 'X' : char('0' + remainder);
if (isbn[12] == correct) {
cout << "Right\n";
} else {
isbn[12] = correct;
cout << isbn << '\n';
}
return 0;
}这个做法依赖格式中的固定下标。正式代码更稳妥:从左到右扫描字符串,忽略连字符,只对遇到的前九个数字累加 数字 × 第几个数字。最后用余数构造正确识别码,与 isbn.back() 比较即可。
识别码计算演示
下面展示样例 0-670-82162-4 的带权和计算:
| 位置 | 字符 | 权重 | 贡献 |
|---|---|---|---|
| 第 1 个数字 | 0 | 1 | 0 |
| 第 2 个数字 | 6 | 2 | 12 |
| 第 3 个数字 | 7 | 3 | 21 |
| 第 4 个数字 | 0 | 4 | 0 |
| 第 5 个数字 | 8 | 5 | 40 |
| 第 6 个数字 | 2 | 6 | 12 |
| 第 7 个数字 | 1 | 7 | 7 |
| 第 8 个数字 | 6 | 8 | 48 |
| 第 9 个数字 | 2 | 9 | 18 |
和为 4,与输入一致所以输出 Right。
注意识别码本身也可能是数字,但它不能参与带权和;因此只在读到前九个数字时累加。
代码
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-07-31 16:21
* update_at: 2026-08-17 22:45
*/
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
string isbn;
cin >> isbn;
int sum = 0;
int digit_count = 0;
// 只计算前 9 个数字,连字符不参与校验。
for (int i = 0; i < (int)isbn.size(); i++) {
if ('0' <= isbn[i] && isbn[i] <= '9') {
digit_count++;
if (digit_count <= 9) {
sum += (isbn[i] - '0') * digit_count;
}
}
}
int remainder = sum % 11;
char correct = remainder == 10 ? 'X' : char('0' + remainder);
if (isbn.back() == correct) {
cout << "Right\n";
} else {
isbn.back() = correct;
cout << isbn << '\n';
}
return 0;
}复杂度
字符串长度固定为
总结
固定格式模拟题最容易错在“哪些字符参与计算”。把连字符跳过,并明确限制只统计前九个数字,就能避免把最后的识别码重复算入。