题解 | #[NOIP2008]ISBN号码#
[NOIP2008]ISBN号码
http://www.nowcoder.com/practice/95712f695f27434b9703394c98b78ee5
我采用的是模块化设计,将本题分解成了几个块,拼接在一起完成了本题.
以下有说不对的地方,敬请指出😅😅
首先,我们看到题目非常长,所以要提炼题目精华,粗略一扫得出
ISBN码包括9位数字 1位识别码和3位分隔符 其规定格式如“x-xxx-xxxxx-x” “-”是分隔符,最后一位是识别码
识别码的计算方法如下:
用所得的结果mod 11 所得的余数即为识别码 如果余数为10,则识别码为大写字母X。
用所得的结果mod 11 所得的余数即为识别码 如果余数为10,则识别码为大写字母X。
编写程序判断输入的ISBN号码中识别码是否正确,如果正确,则仅输出“Right”;如果错误,则输出你认为是正确的ISBN号码。
虽然还是有点多 ,但大概意思是 一串数 ,最后一位是识别码(我理解为校验位), 识别方式为 第一位*1+...+第九位*9 的和(权重) 对 11 取余(校验方式)
再判断校验是否正确,正确返回"Right" ,否则返会正确的这一串数(修正校验位);
题目意思懂了,那首先考虑怎么将这一串数分解出来,如果用暴力法也可以,将每一位数字都设置一个变量,但我偏不.
那太low了,编程编的不让别人看得懂都不好意思了.所以我采用了每一个间隔符前的所有数为一个整形
int a, b, c; char x, x1; scanf("%d-%d-%d-%c", &a, &b, &c, &x);注: 最后一位为字符,因为 10 = X 所以将最后的识别码转为字符将是最后对比的重中之重
然后,开始考虑怎么将 第一位*1+...+第九位*9 的和 求出,因为我把这一串数拆分成了四个整形,所以方便我对每一个整形
进行修改
于是,我想到了设计一个函数来求出这个整形的和,再将三个整形(最后一个是标识符)的和加在一起就是 第一位*1+...+第九位*9 的和
设计这个函数需要 一个数(a,b,c) 和 它的权重(1,2~4,5~9) 暂定这两个.
// 数据 权重 int fin(int number, int dis) { //每位乘 if (number != 0) return fin(number / 10, dis + 1) + number % 10 * dis; else return 0; }
我用的是递归的写法 但是我发现这样写虽然简单,但是求出的和却不是我想要的, 因为题目是从左向右乘以权重的,而我是从右到左
所以需要翻转数字(你以为我会重写??开玩笑😎😎)
于是...
// 数据 int renum(int number) { //反转数字 int result = 0, num = number; while (num) { result = result * 10 + num % 10; num /= 10; } return result; }将这两个结合就可以完成 第一位*1+...+第九位*9的和了
接下来将求出的标识符存放在 X1 中
x1 = (a * 1 + fin(renum(b), 2) + fin(renum(c), 5)) % 11;但此时x1为整形,还不能与x(识别码)做对比,因此再做一下判断,因为x可能是'X'(10)
x1 = x1 == 10 ? 'X' : x1 + '0';注:一个整形加上'0'就可以变成对应的字符(int->char,0~9)
1 + '0' = '1'
9 + '0' = '9'
接下来做判断就可以了
if (x == x1) printf("Right"); else printf("%d-%d-%d-%c", a, b, c, x1);
完整代码
#include <stdio.h> // 数据 int renum(int number) { //反转数字 int result = 0, num = number; while (num) { result = result * 10 + num % 10; num /= 10; } return result; } // 数据 权重 int fin(int number, int dis) { //每位乘 if (number != 0) return fin(number / 10, dis + 1) + number % 10 * dis; else return 0; } int main() { int a, b, c; char x, x1; scanf("%d-%d-%d-%c", &a, &b, &c, &x); x1 = (a * 1 + fin(renum(b), 2) + fin(renum(c), 5)) % 11; x1 = x1 == 10 ? 'X' : x1 + '0'; if (x == x1) printf("Right"); else printf("%d-%d-%d-%c", a, b, c, x1); return 0; }