题解:洛谷 P1055 [NOIP 2008 普及组] ISBN 号码

【题目来源】

洛谷:[P1055 NOIP 2008 普及组] ISBN 号码 - 洛谷 (luogu.com.cn)

【题目描述】

每一本正式出版的图书都有一个 ISBN 号码与之对应,ISBN 码包括 \(9\) 位数字、\(1\) 位识别码和 \(3\) 位分隔符,其规定格式如 x-xxx-xxxxx-x,其中符号 - 就是分隔符(键盘上的减号),最后一位是识别码,例如 0-670-82162-4 就是一个标准的 ISBN 码。ISBN 码的首位数字表示书籍的出版语言,例如 \(0\) 代表英语;第一个分隔符 - 之后的三位数字代表出版社,例如 \(670\) 代表维京出版社;第二个分隔符后的五位数字代表该书在该出版社的编号;最后一位为识别码。

识别码的计算方法如下:

首位数字乘以 \(1\) 加上次位数字乘以 \(2\) ……以此类推,用所得的结果  \(mod\ 11\),所得的余数即为识别码,如果余数为 \(10\),则识别码为大写字母 \(X\)。例如 ISBN 号码 0-670-82162-4 中的识别码 \(4\) 是这样得到的:对 067082162\(9\) 个数字,从左至右,分别乘以 \(1,2,\dots,9\) 再求和,即 \(0\times 1+6\times 2+\dots +2\times 9=158\),然后取 \(158\ mod\ 11\) 的结果 \(4\) 作为识别码。

你的任务是编写程序判断输入的 ISBN 号码中识别码是否正确,如果正确,则仅输出 Right;如果错误,则输出你认为是正确的 ISBN 号码。

【输入】

一个字符序列,表示一本书的 ISBN 号码(保证输入符合 ISBN 号码的格式要求)。

【输出】

一行,假如输入的 ISBN 号码的识别码正确,那么输出 Right,否则,按照规定的格式,输出正确的 ISBN 号码(包括分隔符 -)。

【输入样例】

0-670-82162-4

【输出样例】

Right

【算法标签】

《洛谷 P1055 ISBN号码》 #模拟# #字符串# #NOIP普及组# #2008#

【代码详解】

#include <bits/stdc++.h>  // 包含标准库头文件
using namespace std;

int main()
{
    string s;  // 存储输入的ISBN字符串
    cin >> s;  // 读取输入
  
    int sum = 0;  // 用于计算加权和
    int cnt = 0;  // 当前数字的权重计数器
  
    // 计算前9位数字的加权和
    for (int i = 0; i < s.size() - 1; i++) {
        if (s[i] != '-') {  // 跳过分隔符'-'
            sum += (s[i] - '0') * ++cnt;  // 数字字符转数值并计算加权和
        }
    }
  
    // 计算校验码
    int m = sum % 11;  // 求余数
    char c;  // 存储计算出的校验码
    if (m < 10) {
        c = m + '0';  // 余数0-9转为字符
    } else {
        c = 'X';  // 余数10对应'X'
    }
  
    // 验证校验码
    if (s[s.size() - 1] == c) {  // 校验码正确
        cout << "Right";
    } else {  // 校验码错误
        s[s.size() - 1] = c;  // 修正校验码
        cout << s;  // 输出修正后的ISBN
    }
  
    return 0;
}

【运行结果】

0-670-82162-0
0-670-82162-4
posted @ 2026-02-16 10:35  团爸讲算法  阅读(5)  评论(0)    收藏  举报