1 条题解

  • 0
    @ 2025-5-22 19:47:51

    题意分析

    这道题是关于 ISBN 编号的校验和补全问题。已知 ISBN 是 10 位编码,其中前 9 位代表书籍,最后一位是校验位。校验规则是:把第 1 位数字乘 10、第 2 位乘 9、第 3 位乘 8…… 直到第 10 位乘 1,将所有结果相加后,这个总和必须能被 11 整除。现在输入的 ISBN 中恰好有一个位置是 '?',需要找出这个位置应该填什么数字(或 X)才能让 ISBN 有效,找不到合法解就输出 - 1。需要注意的是:前 9 位只能是 0-9 的数字,第 10 位如果是 10 的话要用 X 表示。

    解题思路

    1. 确定缺失位置

    首先找到输入字符串中 '?' 的位置,记为 pos(从左到右数第 1 位到第 10 位)。比如输入 "15688?111X",'?' 在第 6 位。

    2. 计算已知部分的校验和

    遍历整个 ISBN 的每一位,遇到不是 '?' 的位置就计算它的贡献值:第 i 位(i 从 1 开始)的权重是 (11 - i),比如第 1 位权重是 10,第 2 位权重是 9,依此类推。如果是数字就直接乘权重累加;如果是第 10 位且字符是 X,就按 10 来计算。例如输入 "15688?111X",前 5 位和后 4 位(除了 '?')的数字乘对应权重相加,得到已知部分的和 sum。

    3. 推导缺失位的可能值

    假设缺失位的权重是 w(w = 11 - pos),缺失位需要填的数是 d。整个校验和必须能被 11 整除,即(已知和 sum + w×d)能被 11 整除。 如果缺失位在第 1-9 位:d 只能是 0-9 的数字。需要找到一个 d,使得(sum + w×d)是 11 的倍数,且 d 在 0-9 之间。

    如果缺失位在第 10 位:d 可以是 0-9 或 10(对应 X)。此时 d=10 时要输出 X,否则输出数字,但 d 必须满足 0-10 的范围,并且(sum + w×d)能被 11 整除。

    4. 验证并输出结果

    计算满足条件的 d:

    对于第 1-9 位的缺失位,先算 sum 除以 11 的余数 r,d 需要满足 (w×d) mod 11 = (11 - r) mod 11。解出 d 后,若 d 在 0-9 之间则输出,否则输出 - 1。

    对于第 10 位的缺失位,同样算余数 r,d 的可能值是 (11 - r) mod 11。如果 d=10 就输出 X,d 在 0-9 之间就输出数字,否则输出 - 1。

    代码

    #include<iostream>
    using namespace std;
    int main()
    {
        char s[10];
        while(cin>>s)
        {
            int i,flag,res=0;
            for(i=0;i<10;i++)
            {
                if(s[i]>='0'&&s[i]<='9')//是数字则乘其权值累加 
                    res+=(s[i]-'0')*(10-i);
                else if(s[i]=='X')//是X则加10 
                    res+=10;
                else if(s[i]=='?')//是?则记录其权值 
                    flag=10-i;
            }
            for(i=0;i<=10;i++)//枚举?处数字 
                if((res+flag*i)%11==0)
                    break;
            if(i==10)
            {
                if(flag!=1)//不存在可行解 
                    cout<<"-1"<<endl;
                else//?是X 
                    cout<<"X"<<endl;
            }
            else
                cout<<i<<endl;
        }
        return 0;
    }
    ```
    
    ```
    • 1

    信息

    ID
    1191
    时间
    1000ms
    内存
    64MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者