ISBN 号码

GitHub跳转原题关系图返回列表

按 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 位数字依次乘 1∼91 \sim 9 求和后对 11 取余,余数 10 记作大写 X。

输入一行格式合法的 ISBN 串;识别码正确输出 Right,否则输出补正后的完整 ISBN(保留 -)。样例:0-670-82162-4 输出 Right,0-670-82162-0 输出 0-670-82162-4。

思路

按定义模拟:去掉 - 后的前 9 位数字依次乘 1∼91 \sim 9 求和,对 11 取余即得正确识别码,余 10 记作 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;
}