本文由Jzwalliser原创,发布在CSDN平台上,遵循CC 4.0 BY-SA协议。
因此,若需转载/引用本文,请注明作者并附原文链接,且禁止删除/修改本段文字。
违者必究,谢谢配合。
个人主页:blog.csdn.net/jzwalliser
题目
洛谷 P1055 [NOIP2008 普及组] ISBN 号码
[NOIP2008 普及组] ISBN 号码
题目描述
每一本正式出版的图书都有一个 ISBN 号码与之对应,ISBN 码包括 9 9 9 位数字、 1 1 1 位识别码和 3 3 3 位分隔符,其规定格式如
x-xxx-xxxxx-x
,其中符号-
就是分隔符(键盘上的减号),最后一位是识别码,例如0-670-82162-4
就是一个标准的 ISBN 码。ISBN 码的首位数字表示书籍的出版语言,例如 0 0 0 代表英语;第一个分隔符-
之后的三位数字代表出版社,例如 670 670 670 代表维京出版社;第二个分隔符后的五位数字代表该书在该出版社的编号;最后一位为识别码。识别码的计算方法如下:
首位数字乘以 1 1 1 加上次位数字乘以 2 2 2 ……以此类推,用所得的结果 $ \bmod 11$,所得的余数即为识别码,如果余数为 10 10 10,则识别码为大写字母 X X X。例如 ISBN 号码
0-670-82162-4
中的识别码 4 4 4 是这样得到的:对067082162
这 9 9 9 个数字,从左至右,分别乘以 1 , 2 , … , 9 1,2,\dots,9 1,2,…,9 再求和,即 0 × 1 + 6 × 2 + … … + 2 × 9 = 158 0\times 1+6\times 2+……+2\times 9=158 0×1+6×2+……+2×9=158,然后取 158 m o d 11 158 \bmod 11 158mod11 的结果 4 4 4 作为识别码。你的任务是编写程序判断输入的 ISBN 号码中识别码是否正确,如果正确,则仅输出
Right
;如果错误,则输出你认为是正确的 ISBN 号码。输入格式
一个字符序列,表示一本书的 ISBN 号码(保证输入符合 ISBN 号码的格式要求)。
输出格式
一行,假如输入的 ISBN 号码的识别码正确,那么输出
Right
,否则,按照规定的格式,输出正确的 ISBN 号码(包括分隔符-
)。样例 #1
样例输入 #1
0-670-82162-4
样例输出 #1
Right
样例 #2
样例输入 #2
0-670-82162-0
样例输出 #2
0-670-82162-4
提示
2008 普及组第一题
想法
既然是ISBN码,那么就可以分段输入,把中间的-
筛掉,只留下数字。但是识别码有可能是数字,也有可能是字符,所以统一一下,以字符的格式输入。后面计算出来识别码后,将识别码转换为字符类型,再比对原来的识别码,最后按要求输出。
实现
- 分段输入,过滤掉横杠(C++)或切割字符串(Python)。
- 拼接数字。
- 一次次拆分数字,乘以位权,再累加在一起。
- 取模,将结果转换为字符。如果刚才取模结果为 10 10 10,那就改为 X X X。
- 比对原来的识别码,如果一样那就输出
Right
,否则输出正确的ISBN码。
题解
C++
#include<bits/stdc++.h>
using namespace std;
int main(){
int a,b,c; //用于存放除识别码以外的数字
char d; //用于存放识别码
int isbn; //用于存放算拼接好的数字
int hash = 0; //用于存放过程性数据
int power = 9; //位权
char e,f,g; //用于过滤掉输入中的横杠
cin >> a >> e >> b >> f >> c >> g >> d; //输入
isbn = a * pow(10,8) + b * pow(10,5) + c; //拼接数字
while(isbn){ //一位位拆分数字
hash += (isbn % 10) * power;
isbn /= 10;
power -= 1;
}
char ans = hash % 11 + '0'; //计算识别码,并将其转换为char类型
if(ans == 10 + '0'){ //判断识别码是否是X
ans = 'X';
}
if(ans == d){ //ISBN正确
cout << "Right";
}
else{ //ISBN不正确
cout << a << e << b << f << c << g << ans; //输出正确的ISBN
}
return 0;
}
Python
get = input() #输入
isbn = get[0] + get[2:5] + get[6:11] #拼接数字
hash_ = 0 #用于存放过程性数据
for i in range(9): #拆分一位位数字
hash_ += int(isbn[i]) * (i + 1)
ans = str(hash_ % 11)
if ans == "10": #判断识别码是否是X
ans = "X"
if ans == get[-1]: #ISBN正确
print("Right")
else: #ISBN不正确
print(get[0:12] + ans) #输出正确的ISBN
难度
难度:★☆☆☆☆
这道题比较繁琐,一会儿拼数字,一会儿拆数字,还有字符和整数之间的转换,尤其是C++,明显代码量比Python多多了。不过每一步的难度并不是很高,将所有的操作合并在一起即可。
结尾
这道题你是怎么AC的?欢迎讨论!也希望大犇门多多提出批评啦!