4.4 实验指导教材参考答案
4.4.1 基本循环语句的使用
4.4 实验指导教材参考答案
4.4.1 基本循环语句的使用
一 、 调 试 示 例
最大公约数和最小公倍数:输入两个正整数 m 和 n,输出它们的最大公约数和最小公倍 数。
解答:参见习题程序设计第7 题。
二 、 基 础 编 程 题
(1)求奇数和:读入一批正整数(以零或负数为结束标志),求其中的奇数和。请使用 while
语句实现循环。
解答:参见习题程序设计第1 题。
(2)求最小值:输入一个正整数 n, 再输入 n 个整数,输出最小值。
解答:参见练习4-10。
(3)求整数的位数以及各位数字之和:输入一个整数,求它的位数以及各位数字之和。例 如,123 的位数是 3,各位数字之和是 6。
解答:
# include <stdio.h>
int main (void) {
int count, number, sum;
scanf ("%d", & number);
if (number < 0) { number = - number;
}
count = 0;
sum = 0;
while (number != 0){
sum = sum + number % 10;
number = number / 10;
count ++;
}
printf ("%d %d\n", count, sum);
return 0;
}
(4)韩信点兵:在中国数学史上,广泛流传着一个“韩信点兵”的故事:韩信是汉高祖刘 邦手下的大将,他英勇善战,智谋超群,为汉朝建立了卓越的功劳。据说韩信的数学水平也 非常高超,他在点兵的时候,为了知道有多少兵,同时又能保住军事机密,便让士兵排队报 数:
按从1 至 5 报数,记下最末一个士兵报的数为 1;
再按从1 至 6 报数,记下最末一个士兵报的数为 5;
再按从1 至 7 报数,记下最末一个士兵报的数为 4;
最后按从1 至 11 报数,最末一个士兵报的数为 10;
你知道韩信至少有多少兵?
解答:
# include <stdio.h>
int main (void) {
int n;
n = 0;
while (n % 5 != 1 || n % 6 != 5 || n % 7 != 4 || n % 11 != 10){
n++;
}
printf ("%d\n", n);
return 0;
}
(5)求序列前 N 项和:输入一个正整数 n,输出 2/1 + 3/2 + 5/3 + 8/5 + …的前 n 项之和(该
序列从第二项起,每一项的分子是前一项分子与分母的和,分母是前一项的分子),保留 2
位小数。
解答:参见习题程序设计第3 题。
(6)求 a+aa+aaa+aa…a:输入两个正整数 a 和 n,求 a + aa + aaa + aa…a(n 个 a)之和。试 编写相应程序。
解答:参见习题程序设计第4 题。
三 、 改 错 题
序列求和:输入一个正实数eps,计算并输出下式的值,直到最后一项的绝对值不大于
于eps(保留 6 位小数)。请使用 do-while 语句实现循环。(源程序 error04_2.cpp)
1 1 1 1 1
1 ...
4 7 10 13 16
s = − + −
+ − +提醒:教材上此题对最后一项取值的描述为“精确到最后一项的绝对值小于 eps”。下次印 刷时将修改一致。
解答1:
# include <stdio.h>
# include <math.h>
int main (void) {
int flag;
double denominator, eps, item, sum;
flag = 1; denominator = 1 ; item = 1.0; sum = 0;
scanf("%lf", &eps);
do{
item = flag * 1.0 / denominator;
sum = sum + item;
flag = -flag;
denominator = denominator + 3;
}while (fabs (item) > eps) ; printf ("sum = %.6f\n", sum);
return 0;
}
解答2:用 while 实现,参见练习 4-3。
四 、 拓 展 编 程 题
(1))猜数字游戏:输入一个100 以内的正整数,用户再输入一个数对其进行猜测,需要你
编写程序自动对其进行比较,并提示大了(“Too big”),还是小了(“Too small”),相等表示 猜到了。如果猜到,则结束程序。程序还要求统计猜的次数,如果1 次猜出该数,提示“Bingo!”;
如果3 次以内猜到该数,则提示“Lucky You!”;如果超过 3 次但是在 N(>3)次以内(包括 第N 次)猜到该数,则提示“Good Guess!”;如果超过 N 次都没有猜到,则提示“Game Over”,
并结束程序。如果在到达N 次之前,用户输入了一个负数,也输出“Game Over”,并结束程
序。试编写相应程序。
解答:参见练习4-6。
(2)兔子繁衍问题:一对兔子,从出生后第 3 个月起每个月都生一对兔子。小兔子长到第
3 个月后每个月又生一对兔子。假如兔子都不死,请问第 1 个月出生的一对兔子,至少需要
繁衍到第几个月时兔子总数才可以达到N 对?试编写相应程序。
解答:参见习题程序设计第11 题。
(3)高空坠球:皮球从 height 米的高度自由落下,触地后反弹到原高度的一半,再落下,
再反弹,如此反复。皮球在第n 次落地时,在空中经过的路程是多少米?第 n 次反弹的高度
是多少?试编写相应程序,输出保留1 位小数。
提醒:教材上此题的描述为“皮球在第n 次反弹落地时,在空中经过的路程是多少米?”。
下次印刷时将修改一致。
输入输出示例改为:
10 2 20.0 2.5
解答:参见习题程序设计第8 题。
(4)黑洞数:黑洞数也称为陷阱数,又称“Kaprekar 问题”,是一类具有奇特转换特性的数。
任何一个数字不全相同的三位数,经有限次“重排求差”操作,总会得到495。最后所得的
495 即为三位黑洞数。所谓“重排求差”操作即组成该数的数字重排后的最大数减去重排后 的最小数。(6174 为四位黑洞数)
例如,对三位数207:
第1 次重排求差得:720-027=693;
第2 次重排求差得:963-369=594;
第3 次重排求差得:954-459=495;
以后会停留在495 这一黑洞数。如果三位数的 3 个数字全相同,一次转换后即为 0。
试求出任意输入三位数重排求差的过程。
解答:
# include <stdio.h>
int main (void) {
int a, b, c, i, max, min, number, t;
scanf("%d", &number);
i = 1;
do {
a = number / 100;
b = (number / 10) % 10;
c = number % 10;
if (a < b) {
t = a; a = b; b = t;
}
if (a < c) {
t = a; a = c; c = t;
}
if (b < c) {
t = b; b = c; c = t;
}
max = a * 100 + b * 10 + c;
min = c * 100 + b * 10 + a;
number = max - min;
printf ("%d: %d - %d = %d\n", i, max, min, number);
i++;
} while (number != 495);
return 0;
}