4.4 实验指导教材参考答案
4.4.2 嵌套循环
一 、 调 试 示 例
求e:输入一个正整数 n,计算下式的和(保留 4 位小数),要求使用嵌套循环。
! 1
! 3 1
! 2 1
! 1 1 1
e = + + + + + n
解答:参见练习4-6。
提醒:PTA 题目集中,要求输出结果保留 8 位小数。
二 、 基 础 编 程 错
(1)用两种方法求 e:输入一个正整数 n,用两种方法分别计算下式的和(保留 4 位小数)。
! 1
! 3 1
! 2 1
! 1 1 1
e = + + + + + n
① 使用一重循环,不使用自定义函数。
② 定义和调用函数 fact(n)计算 n 的阶乘。
提醒:求e 可以采用 3 种方法编程,即一重循环(源程序 1)、使用函数(源程序 2)和嵌套
循环(调试示例),在PTA 题目集中,只体现为 1 道题目,不再区分实现途径。
解答:
源程序1
# include <stdio.h>
int main(void) {
int i, n;
double e, product;
scanf("%d", &n);
e = 1;
product = 1;
for (i = 1; i <= n ; i++){
product = product * i;
e = e + 1.0 / product;
}
printf ("%.8f\n", e);
return 0;
}
(2)
# include <stdio.h>
double fact (int n);
int main(void) {
int i, n;
double e;
scanf("%d", &n);
e = 1;
for (i = 1; i <= n ; i++){
e = e + 1.0 / fact (i);
}
printf ("%.8f\n", e);
return 0;
}
double fact (int n) {
double product;
int i;
product = 1;
for (i = 1; i <= n; i++){
product = product * i;
}
return product;
}
(2)验证哥德巴赫猜想:任何一个大于 2 的偶数均可表示为两个素数之和。例如 4=2+2,
6=3+3,8=3+5,…,18=5+13。要求将输入的一个偶数表示成两个素数之和。
提醒:教材上此题对哥德巴赫猜想的描述为“任何一个大于等于6 的偶数均可表示为两个素 数之和”。下次印刷时将修改一致。
分析:(1)在一行中按照格式“N = p + q”输出 N 的素数分解,其中 p≤q 均为素数。又因 为这样的分解不唯一(例如24 还可以分解为 7+17),要求必须输出所有解中 p 最小的解。
(2)定义变量 flag 标识素数,flag 为 1:p 和 q 皆为素数;flag 为 0:p 或 q 不是素数。
解答:
# include <stdio.h>
# include <math.h>
int main (void) {
int flag, i, j, k, p, q, m, n;
scanf ("%d", &n);
if (n == 4) {
printf("4 = 2 + 2\n");
} else{
for (p = 3; p <= n/2; p = p + 2) {
flag = 1;
m = (int)sqrt(p);
for (k = 2; k <= m; k++) { if (p % k== 0) { flag = 0;
break;
}
}
if (flag == 1) { q = n - p;
m = (int)sqrt(q);
for (k = 2; k <= m; k++) { if (q % k == 0) { flag = 0;
break;
} } }
if (flag == 1){
printf ("%d = %d + %d", n, p, q);
break;
}
} }
return 0;
}
(3)换硬币:将一笔零钱(大于 8 分,小于 1 元,精确到分)换算成 1 分、2 分和 5 分的
硬币组合。输入金额,输出共有多少种换法?要求硬币面值按5 分、2 分、1 分顺序,各类
硬币数量依次从大到小的顺序,输出各种换法。
解答:参见习题程序设计第5 题。
(4)水仙花数:输入两个正整数 m 和 n(m≥1, n≤1000),输出 m 到 n 之间的所有水仙花数。
水仙花数是指各位数字的立方和等于其自身的数。例如153 的各位数字的立方和是 13 + 53 + 33 = 153。试编写相应程序。
提醒:此题与PTA 题目集的题目描述有所不同,PTA 题目集中题目的描述及解答参见习题 程序设计第6 题。
解答:
# include <stdio.h>
int main (void) {
int digit, i, m, n, number, sum;
printf ("Input m:");
scanf ("%d", &m);
printf ("Input n:");
scanf ("%d", &n);
for (i = m; i <= n; i++){
number = i;
sum = 0;
while (number != 0){
digit = number % 10;
number = number / 10;
sum = sum + digit * digit * digit;
}
if (sum == i) { printf("%d\n", i);
} }
return 0;
}
(5)输出三角形字符阵列图形:输入一个正整数 n(n<7),输出 n 行由大写字母 A 开始构 成的三角形字符阵列图形。
解答:
# include <stdio.h>
int main (void) {
int i, j, n;
char ch;
ch = 'A';
scanf ("%d", &n);
for (i = n; i >= 1; i--) { for (j = 1; j <= i; j++) {
printf ("%c ", ch);
ch++;
}
printf("\n");
}
return 0;
}
三 、 改 错 题
找完数:找出200 以内的所有完数,并输出其因子。一个数若恰好等于它的各因子之和,
即称其为完数,例如,6 = 1 + 2 + 3,其中 1、2、3 为因子,6 为因子和。
提醒:此题与PTA 题目集的题目略有不同,PTA 题目需要输入查找完数的范围。
解答(PTA):
# include <stdio.h>
# include <math.h>
int main() {
int flag, i, j, m, n, s;
scanf ("%d %d", &m, &n);
flag = 0;
if (m == 1) {
printf ("1 = 1\n");
m++;
flag = 1;
}
for (i = m; i <= n; i++) { s = 0;
for (j = 1; j <= i / 2; j++) { if (i % j == 0) { s = s + j;
} }
if (i == s) { flag = 1;
printf ("%d = 1", i);
for (j = 2; j <= i / 2; j++){
if (i % j == 0) { printf (" + %d", j);
} }
printf("\n");
} }
if (flag == 0) { printf("None\n");
}
return 0;
}
四 、 拓 展 编 程 题
(1)从高位开始逐位输出一个整数的各位数字:输入一个整数,从高位开始逐位分割并 输出它的各位数字。
解答:
# include <stdio.h>
int main (void) {
int digit, n, temp, pow;
scanf ("%d", &n);
if (n < 0) { n = - n;
}
temp = n;
pow = 1;
while (temp > 10) { pow = pow * 10;
temp = temp / 10;
}
while ( pow >= 1 ) { digit = n / pow;
n = n % pow;
pow = pow / 10;
printf ("%d ", digit);
}
printf ("\n");
return 0;
}
(2)梅森数:形如 2n-1 的素数称为梅森数(Mersenne Number)。例如 22-1=3、23-1=
7 都是梅森数。1722 年,双目失明的瑞士数学大师欧拉证明了 231-1=2147483647 是一个
素数,堪称当时世界上“已知最大素数”的一个记录。输入一个正整数n(n<20),编程输出
所有不超过2^n - 1 的梅森数。
解答:
# include <stdio.h>
# include <math.h>
int main (void) {
int flag, i, j, k, n, number, prime;
scanf("%d", &n);
flag = 0;
for (i = 2; i <= n; i++) {
number = (int) pow (2, i) -1;
k = (int) sqrt (number);
prime = 1;
for (j = 2; j <= k; j++) {
if (number % j == 0) { prime = 0;
break;
} }
if (prime != 0) {
printf ("%d\n", number);
flag = 1;
} }
if (flag == 0) { printf("None\n");
} return 0;
}