洛谷 P1055 [NOIP2008 普及组] ISBN 号码

本文由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码,那么就可以分段输入,把中间的-筛掉,只留下数字。但是识别码有可能是数字,也有可能是字符,所以统一一下,以字符的格式输入。后面计算出来识别码后,将识别码转换为字符类型,再比对原来的识别码,最后按要求输出。

实现

  1. 分段输入,过滤掉横杠(C++)或切割字符串(Python)。
  2. 拼接数字。
  3. 一次次拆分数字,乘以位权,再累加在一起。
  4. 取模,将结果转换为字符。如果刚才取模结果为 10 10 10,那就改为 X X X
  5. 比对原来的识别码,如果一样那就输出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的?欢迎讨论!也希望大犇门多多提出批评啦!

  • 23
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值