1.ISBN号码
题目描述:
每一本正式出版的图书都有一个ISBN号码与之对应,ISBN码包括9位数字、1位识别码和3位分隔符,其规定格式如“x-xxx-xxxxx-x”,其中符号“-”是分隔符(键盘上的减号),最后一位是识别码,例如0-670-82162-4就是一个标准的ISBN码。ISBN码的首位数字表示书籍的出版语言,例如0代表英语;第一个分隔符“-”之后的三位数字代表出版社,例如670代表维京出版社;第二个分隔之后的五位数字代表该书在出版社的编号;最后一位为识别码。
识别码的计算方法如下:
首位数字乘以1加上次位数字乘以2……以此类推,用所得的结果mod 11,所得的余数即为识别码,如果余数为10,则识别码为大写字母X。例如ISBN号码0-670-82162-4中的识别码4是这样得到的:对067082162这9个数字,从左至右,分别乘以1,2,…,9,再求和,即0×1+6×2+……+2×9=158,然后取158 mod 11的结果4作为识别码。
题目任务:
编写程序判断输入的ISBN号码中识别码是否正确,如果正确,则仅输出“Right”;如果错误,则输出你认为是正确的ISBN号码。
输入输出要求:
输入要求:只有一行,是一个字符序列,表示一本书的ISBN号码(保证输入符合ISBN号码的格式要求)。
输出要求:共一行,假如输入的ISBN号码的识别码正确,那么输出“Right”,否则,按照规定的格式,输出正确的ISBN号码(包括分隔符“-”)。
输入输出案例:
案例1
输入:0-670-82162-4
输出:Right
案例2
输入:0-670-82162-0
输出:0-670-82162-4
代码实现:
#include <stdio.h>
int main()
{
//因为涉及到‘X’到数字的转换,所以需要用字符类型接收,我们干脆直接定义一个字符数组
char arr[13] = { 0 };
//本人采用循环控制,%c输入的方式输入
for (int i = 0; i < 13; i++)
{
scanf("%c", &arr[i]);
}
//暴力法求各位数的和
int num = (arr[0] - '0') * 1 + (arr[2] - '0') * 2 + (arr[3] - '0') * 3 +
(arr[4] - '0') * 4 + (arr[6] - '0') * 5 + (arr[7] - '0') * 6 +
(arr[8] - '0') * 7 + (arr[9] - '0') * 8 + (arr[10] - '0') * 9;
//取余
int mod = num % 11;
//判断识别码是否为‘X’:如果是,将它的值改为int类型的数字10;如果不是,将字符转换成整型数字。
int arr_id = arr[12] == 'X' ? 10 : arr[12] - '0';
//如果识别码不等于余数
if (mod != arr_id)
{
//将余数转换成字符格式:如果mod等于10,就要转化为字符‘X’;若不等于,则要将数字转换成字符。
arr[12] = mod == 10 ? 'X' : mod + '0';
printf("%s", arr);
}
else
printf("Right");
return 0;
}
补充:
这道题的难点在于字符和数值的转换,但当我们了解某些特性,那么解题就能游刃有余。
我们观察ASCLL码表,发现字符0~9有对应的十进制值。那么我们就可以以字符 ‘0’ 为之间量进行加减。例如:字符 ‘1’ - 字符 ‘0’ = 1 。反过来就是 数字1 + 字符 ‘0’ =字符 ‘1’ 。
并且,题目当中使用了多个三目操作符,使我们的代码看起来相对整洁,不那么杂乱。
当然,本题的代码并不是最优解,尤其是注释部分的暴力解法,只是为了理解起来、看起来不那么复杂。
2.统计包含数字9的数的个数
题目描述:
今年是2022年,KiKi想知道1~2022中有多少个包含数字9的数。包含数字的数是指有某一位是“9”的数,例如“2019”、“199”等。
题目任务:
输出1~2022中共有多少个数包含数字9。
输入输出要求:
输入:无
输出:1~2022中共有多少个数包含数字9
代码实现:
#include <stdio.h>
int main()
{
int i = 0;
//使用一个变量描述个数
int count = 0;
for (i = 1; i <= 2022; i++)
{
//要使用i但不改变i的值就用临时变量代替
int tmp = i;
//个位、十位、百位、千位依次判断是不是数字9
while (tmp)
{
if (tmp % 9 == 0)//也可写成 (tmp % 10 == 9)
{
count++;
break;
}
tmp /= 10;
}
}
printf("%d", count);
return 0;
}
补充:
其实本题并不难,核心的地方在于怎么取到每个数的个位、十位、百位等等,并单独拿出来做判断。我们不妨这样设想:我们定义的是int类型的变量,那么变量存储的数值一定不可能有小数,即2022 / 10 =202 ,202 % 10 = 2 ,这样我们就得到了十位上的数字。重复这个步骤,就能实现功能。
其次我们要掌握一个思想:临时变量。可以看到注释部分:要使用i但不改变i的值就用临时变量代替。当我们写一个循环时,发现要用到循环体的数值,并且可能会进行一些运算改变它的值,那么我们可以发循环体的数值赋值给一个新的变量,用这个新的变量去进行下一步的运算。
3.水仙花数
题目描述:
春天是鲜花的季节,水仙花就是其中最迷人的代表,数学上有个水仙花数,他是这样定义的: “水仙花数”是指一个三位数,它的各位数字的立方和等于其本身,比如:153=1^3+5^3+3^3。 现在要求输出所有在m和n范围内的水仙花数。
题目任务:
判断一个范围内有没有水仙花数,如果有,就依次从小到大打印出来;如果没有,则就输出“no”。(多组输入输出)。
输入输出要求:
输入要求:输入数据有多组,每组占一行,包括两个整数m和n(100 ≤ m ≤ n ≤ 999)。
输出要求:对于每个测试实例,要求输出所有在给定范围内的水仙花数,就是说,输出的水仙花数必须大于等于m,并且小于等于n,如果有多个,则要求从小到大排列在一行内输出,之间用一个空格隔开; 如果给定的范围内不存在水仙花数,则输出no; 每个测试实例的输出占一行。
输入输出案例:
案例1
输入:100 120
300 380
输出:no
370 371
代码实现:
#include <stdio.h>
#include <math.h>
int main()
{
int n = 0;
int m = 0;
int i = 0;
//用一个标记来判断范围内有没有水仙花数,如果但凡有一个,那么flag的值就改为1;如果一个没有,那flag的值不变。
int flag = 0;
while (scanf("%d%d", &n, &m) != EOF)
{
getchar();
for (i = n; i <= m; i++)
{
if (pow(i % 10, 3) + pow(i / 10 % 10, 3) + pow(i / 100 % 10, 3) == i)
{
printf("%d ", i);
flag = 1;
}
}
if (flag == 0)
printf("no\n");
}
return 0;
}
补充:
这个题也没有太大的难度,无非使用了计算次方的pow函数。pow(a,b),用数学表达为:a^b。例如:pow(2,3),计算的是 2^3 = 8,8作为函数的返回值。
这个题着重在于falg的使用,我们可以自行体会。
4.考官打分
题目描述:
有7位考官,从键盘输入若干组成绩,每组7个分数(百分制),去掉一个最高分和一个最低分,输出每组的平均成绩。(注:本题有多组输入)
题目任务:
输入7个整数(0~100),代表7个成绩,用空格分隔。输出去掉最高分和最低分的平均成绩,小数点后保留2位,每行输出后换行。
输入输出要求:
输入要求:每一行,输入7个整数(0~100),代表7个成绩,用空格分隔。
输出要求:每一行,输出去掉最高分和最低分的平均成绩,小数点后保留2位,每行输出后换行。
输入输出案例:
案例1
输入:99 45 78 67 72 88 60
输出:73.00
代码实现:
#include <stdio.h>
int main()
{
int arr[7] = { 0 };
int i = 0;
while (scanf("%d%d%d%d%d%d%d", &arr[0], &arr[1], &arr[2], &arr[3], &arr[4], &arr[5], &arr[6]) != EOF)
{
//每次循环sum、max、min的值都不变。为了不影响下次输入,需要重置数值。
int sum = 0;
int max = 0;
int min = 100;
for (i = 0; i < 7; i++)
{
//判断谁最大
if (arr[i] > max)
max = arr[i];
//判断谁最小
if (arr[i] < min)
min = arr[i];
//求和
sum += arr[i];
}
//整数*浮点数=浮点数
double num = (sum - max - min) * 1.0 / 5;
printf("%.2lf\n", num);
}
return 0;
}
补充:
这个题要求是多组输入,所以我在scanf函数上下文章。用了一个比较low的方法实现功能。大家也可以用指针,看起来会整洁一些。
本题的核心是:这个程序是不会结束的,即定义的sum、max、min会随着程序往下走改变。我们要做的是一层循环结束后,将sum、max、min的值重置,看起来像是一个“新的程序”。
谁最大谁最小的这个算法,思想很简单,我们可以自行体会。