#define int long long     // 把int定义成long long类型,防止大数计算时溢出
using namespace std;      // 使用标准命名空间

signed main()  // 主函数,signed相当于int,因为上面把int定义成了long long
{
    string s;    // 定义字符串s,用来存储ISBN号码
    cin >> s;    // 输入ISBN号码
    
    int cnt = 1; // 计数器,从1开始,对应公式中的乘数
    int sum = 0; // 总和,用来计算加权和
    
    // 遍历字符串中除了最后一个字符的所有字符(最后一个字符是识别码)
    for(int i = 0; i < s.size() - 1; i++)
    {
        // 如果当前字符不是分隔符'-'
        if(s[i] != '-')
        {
            // 计算加权和:将字符转换成数字乘以计数器,然后模11防止过大
            // s[i]-48 是把字符'0'-'9'转换成数字0-9
            sum += ((s[i] - 48) * cnt) % 11;
            cnt++;  // 计数器加1,准备计算下一个数字
        }
    }
    
    sum %= 11;  // 最后再对11取模,得到最终的余数
    
    // 如果余数是10,识别码应该是'X'
    if(sum == 10)
    {
        // 如果输入的最后一个字符确实是'X',说明识别码正确
        if(s[s.size() - 1] == 'X')
        {
            cout << "Right";  // 输出"Right"
        }
        else  // 如果最后一个字符不是'X'
        {
            // 输出正确的ISBN号码:前面的字符不变,只修改识别码
            for(int i = 0; i < s.size() - 1; i++)
            {
                cout << s[i];  // 输出前面的所有字符
            }
            cout << "X";  // 输出正确的识别码'X'
        }
    }
    else  // 如果余数不是10,识别码应该是数字
    {
        // 如果输入的最后一个字符的数字等于计算出的余数
        if((s[s.size() - 1] - 48) == sum)
        {
            cout << "Right";  // 输出"Right"
        }
        else  // 如果最后一个字符的数字不等于计算出的余数
        {
            // 输出正确的ISBN号码:前面的字符不变,只修改识别码
            for(int i = 0; i < s.size() - 1; i++)
            {
                cout << s[i];  // 输出前面的所有字符
            }
            cout << sum;  // 输出正确的识别码(数字)
        }
    }
    
    return 0;  // 程序正常结束
}

计算识别码的步骤:

取出前9位数字(跳过分隔符'-')

第1个数字×1 + 第2个数字×2 + ... + 第9个数字×9

把上面计算的和除以11,看余数是多少

如果余数是10,识别码就是'X';否则识别码就是余数本身

程序运行逻辑:

如果输入的ISBN号码识别码正确,就输出"Right"

如果识别码错误,就输出正确的ISBN号码(只修改最后一个识别码字符)

举例说明:

比如ISBN号码:0-670-82162-4

前9位数字是:0,6,7,0,8,2,1,6,2

计算:0×1 + 6×2 + 7×3 + 0×4 + 8×5 + 2×6 + 1×7 + 6×8 + 2×9 = 158

158 ÷ 11 = 14余4

所以识别码应该是4,与输入的识别码一致,输出"Right"

//啥也不是,不动脑

1 条评论

  • @ 2025-11-2 17:43:20

    你是个人

    • 1