你也可以上程序咖(https://meta.chengxuka.com),打开大学幕题板块,不但有答案,讲解,还可以在线答题。
一、选择题
1.以下程序段( )不能实现求 s = 1+2+...+n-1。
A.
int i, n, s=0; scanf("%d", &n); for(i=1; i<n; i++){ s=s+i; }
B.
int i,n,s=0; scanf("%d",&n); for(i=1; i<=n-1;++i){ s=s+i; }
C.
int i,n, s≈0; scanf("%d", &n); for(i=n-1;i>0;i--){ s=s+i; }
D.
int i,n,s=0; scanf("%d",&n); for(i=n-1;i>0;++i){ s=s+i; }
答:D
解析:
选项 A、B、C 的代码都可以实现题目要求。但是选项 D 的代码执行起来是个死循环,i 的值从 n-1 开始,然后++i,循环的结束条件是 i>0,i 的值越加越大,一直大于 0,条件永远成立。实现的并不是从 1 累加到 n-1。
2.输入65 14 <Enter>
,以下程序段的输出结果为( )。
int m, n; scanf("%d%d", &m,&n); while(m!=n) { while(m>n) m=m-n; while(n>m) n=n-m; } printf( "m=%d\n", m);
A. m=3
B. m=2
C. m=1
D. m=0
答:C
解析:
m 的初始值为 65,n 的初始值为 14。第一个while 的条件 m!=n,是成立的。执行里面的循环体。
第二个while 的条件 m >n,此时也是成立的,执行里面的循环体 m=m-n;执行后 m 的值为 51,因为是循环语句,要再次判断条件是否成立,m>n 依然成立,再执行一次循环体 m=m-n;执行后 m 的值为37。再次判断条件 m>n 依然成立,再一次执行循环体 m=m-n;执行后 m 的值为23。再次判断条件 m>n 依然成立,再一次执行循环体 m=m-n;执行后 m 的值为 9 。再次判断条件 m>n不成立,结束这个循环。
程序继续执行到第三个 while 循环,条件是 n>m,此时 m 的值为 9,n 的值为 14,条件成立,执行里面的循环体 n=n-m,执行后 n 的值为 5。再来判断循环条件 n>m,已经不成立了。结束这个循环。
此时里面的两个循环作为最外层的循环的循环体,结束这次执行之后,要再来判断最外层循环的条件 m!=n,此时 m 的值为 9,n 的值为 5。条件成立,要再次执行里面的循环体,就是两个里层循环。先看第二个循环条件 m>n,成立的,那吗执行里面的循环体 m=m-n,执行后 m 的值为 4,再来判断条件 m>n,已经不成立了,结束这个循环。
程序继续执行到第三个循环,条件是 n>m,此时 m 的值为 4,n 的值为 5,条件成立,执行里面的循环体 n=n-m,执行后 n 的值为 1。再来判断循环条件 n>m,已经不成立了。结束这个循环。
这两个循环执行结束后,要继续判断最外层的循环条件 m!=n,此时 m 的值为 4,n 的值为 1,条件成立,再次进去执行里面的两个内层循环。先来判断第二个循环条件 m>n,成立的,执行里面的循环体 m=m-n,执行后,m 的值为 3,再来判断条件 m>n,依然成立,执行里面的循环体 m=m-n,执行后,m 的值为2,再来判断条件 m>n,依然成立,执行里面的循环体 m=m-n,执行后,m 的值为 1。再来判断条件 m>n,此时已经不成立了。结束这个循环。
程序继续执行到第三个while循环,条件是 n >m,此时 m 的值为 1,n 的值也为 1。条件不成立,结束这个循环。
然后要再来判断外层循环的条件 m!=n,此时 m 的值为 1 ,n 的值也为 1。条件不成立,结束这个外层循环。
程序继续向下执行,打印输出语句,m 的值为 1。
3.C语言中 while 和 do-while 循环的主要区别是( )。
A. do-while 的循环体至少无条件执行一次
B. while 的循环控制条件比 do-while 的循环控制条件严格
C. do-while 允许从外部转到循环体内
D. do-while 的循环体不能是复合语句
答:A
解析:
while 循环是先判断条件,条件成立再执行循环体。
do-while 循环是先执行循环体,再判断条件是否成立。即使条件不成立,也已经执行一次循环体了。
4.下列叙述中正确的是( )。
A. break 语句只能用于 switch 语句体中
B. continue 语句的作用是使程序的执行流程跳出包含它的所有循环
C. break 语句只能用在循环体内和 switch 语句体内
D. 在循环体内使用 break 语句和 continue 语句的作用相同
答:C
解析:
break 语句可以使用在 switch 中。也可以使用在循环中,表示强制结束循环。
break 语句用在循环中表示强制结束循环,无论循环条件是否成立,循环都彻底的结束了。而 continue 语句,也是用于强制结束循环,但只是结束这一次循环,循环下次继续执行。
5.下列叙述中正确的是( )。
A. do-while 语句构成的循环不能用其他语句构成的循环来代替
B. do-while 语句构成的循环只能用 break 语句退出
C. 用 do-while 语句构成的循环,在 while 后的表达式为非零时结束循环
D. 用 do-while 语句构成的循环,在 while 后的表达式为零时结束循环
答:D
解析:
C 语言中的三种循环语句 for,while 和 do-while ,其实是可以互相替代的,只是写法不同。有些情况使用 for 循环比较方便,有些情况使用 while 比较方便,有些时候使用 do-while 比较方便。这三种循环的成立条件,都是非零,就会执行循环体。所以此题目的正确答案是选项 D。
6.下列程序段的输出结果是( )。
int i; for(i=1; i<6; i++){ if(i%2!=0){ printf("#"); continue; } printf("*"); }
A. #*#*#
B. #####
C. *****
D. *#*#*
答:A
解析:
此代码实现的是判断变量 i 的值,如果为奇数,打印 #
, 如果为偶数,打印 *
。
变量 i 的初始值为1,循环条件为 i<6,成立里面的循环体,是一个 if 语句,继续判断 if 语句的条件,i%2!=0,也是成立的,打印一个 #
,然后执行 continue 语句,结束本次循环,不打印 *
,
然后执行 i++,此时 i 的值为 2 ,循环条件依然成立,判断 if 语句的条件,不成立,那么不执行 if 里的代码,跳过 if 语句执行后面的打印语句,打印出 *
,
然后执行 i++,此时 i 的值为 3,循环条件依然成立,判断 if 语句的条件,成立的,执行 if 语句里的内容,打印 #
,然后执行 continue,结束这次循环。
然后执行 i+=,此时 i 的值为 4,循环条件依然成立,判断 if 语句的条件,不成立,那吗不执行 if 里的代码,跳过 if 语句执行后面的打印语句,打印出 *
,
然后执行 i++,此时 i 的值为 5,循环条件依然成立,判断 if 语句的条件,成立的,执行 if 语句里的内容,打印 #
,然后执行 continue,结束这次循环。
然后执行 i++,此时 i 的值为 6,循环条件不成立了,结束 for 循环。
二、填空题
1.执行以下程序段后,变量 i 的值是( ),s 的值是( )。
int i, s=0; for(i=1; i<=10: i=i+3) s=s+i;
答:13,22
解析:
变量 i 的初始值为 1,s 的初始值为 0。for 循环的条件是 i <= 10,
第一次循环:i 的值为 1,s 的值为 0,执行循环体的内容后,s 的值为 1。然后执行 i=i+3,然后 i 的值为 4。
第二次循环:i 的值为 4,s 的值为 1,执行循环体的内容后,s 的值为 5。然后执行 i=i+3,然后 i 的值为 7。
第三次循环:i 的值为 7,s 的值为 5,执行循环体的内容后,s 的值为12 。然后执行 i=i+3,然后 i 的值为 10。
第四次循环:i 的值为 10,s 的值为 12,执行循环体的内容后,s 的值为 22。然后执行 i=i+3,然后 i 的值为 13。
不再满足循环的条件了,循环结束。
2.下列程序段的输出结果是( )。
for(int i=14; i>1; i/=3) printf("%d#",i);
答:14#4#
解析:
变量 i 的初始值是 14,for 循环的条件是 i>1,
第一次循环:i 的值为 14,执行循环体的内容后,打印 14# 。然后执行 i/=3,然后 i 的值为 4。
第二次循环:i 的值为 4,执行循环体的内容后,打印 4# 。然后执行 i/=3,然后 i 的值为 1。
不再满足循环的条件了,循环结束。
3.以下程序段 A 的输出结果是( ),程序段 B 的输出结果是( )。
程序段 A
int num=0,s1=0; while(num<=2) { num++; s1=s1+num; } printf("s1=%d\n", s1);
程序段B
int num=0,s2=0; while( num<=2) { s2=s2+num; num++; } printf("s2=%d\n",s2);
答:s1=6,s2=3
解析:
程序段 A:
变量 num 的初始值是0,s1 的初始值也是 0,while 循环的条件是 num<=2,
第一次循环,num 的值为 0,执行 num++ 后,num 的值为 1,然后执行 s1=s1+num 后,s1 的值为1,
第二次循环,num 的值为 1,执行 num++ 后,num 的值为 2,然后执行 s1=s1+num 后,s1 的值为3,
第三次循环,num 的值为 2,执行 num++ 后,num 的值为 3,然后执行 s1=s1+num 后,s1 的值为6,
再判断 while 循环的条件,不成立了,循环结束。
程序段 B:
变量 num 的初始值是0,s2 的初始值也是 0,while 循环的条件是 num<=2,
第一次循环,num 的值为 0,执行 s2=s2+num 后,s2 的值为 0 ,执行 num++ 后,num 的值为 1,
第二次循环,num 的值为 1,执行 s2=s2+num 后,s2 的值为 1 ,执行 num++ 后,num 的值为 2,
第三次循环,num 的值为 2,执行 s2=s2+num 后,s2 的值为 3 ,执行 num++ 后,num 的值为 3,
再判断 while 循环的条件,不成立了,循环结束。
4.求序列和。计算并输出 s=1+12+ 123+ 1234+12345 的值。请填空。
int i,s=0, t=0; for(i=1; i<=5; i++){ t=__________+i; s=s+t; } printf("s=%d\n", s);
答:t*10
解析:循环中 i 的值是从 1 到 5。只要让 t 的值分别为 1,12,123,1234,12345即可。所以思考 t = ? 加 i。每次 ? 的值就该是 0,10,120,1230,12340 即可。
5.以下程序段A的输出结果是( ),程序段B的输出结果是( )。
程序段 A
int num=0; while(num<6){ num++; if(num==3) break; printf("%d#",num); }
程序段 B
int num=0; while(num<6) { num++; if(num==3) continue; printf("%d#",num); }
答:1#2#,1#2#4#5#6#
解析:这两段代码考察的是 break 和 continue 的用法的区别。
break 执行后,会彻底的结束循环。所以 num 的值为 3,满足条件后,整个循环就结束了,哪怕循环条件依然成立。打印到 num 的值为2。
continue 执行后,结束这次循环,但是循环还是会继续。所以 num 的值为 3,满足条件后,只是结束了这次循环,所以打印的时候,只是跳过了 3,后面的继续。
6.输入82pay! <Enter>
, 以下程序段的输出结果为( )。
char ch; int i; for(i=1; i<=6; i++){ ch=getchar(); if(ch>='a' && ch<='z') ch=(ch+5-'a')%26+'a'; else 1f(ch>='0' & ch<='9') ch=(ch+2-'0')%10+'0'; putchar(ch); }
答:04ufd!
解析:这段代码实现的是将输入的自负,如果是数字,后移 2 位。如果是字母,后移 5 位。其他字符原样输出。
输入 8,输出 0。输入 2,输出 4。
输入 p,输出 u。输入 a,输出 f。输入 y,输出 d。输入 !,输出还是 !。
7.阅读下列程序段并回答问题。
int i, j, k = 0, m = 0; for (i = 0; i < 2; i++) { ; /*第3行*/ for (j = 0; j < 3; j++) k++; m++; /*第6行*/ } printf("k=%d, m=%d\n", k, m);
(1) 程序段的输出是( )
(2) 将第6行改为"m=m+k;", 程序段的输出是( )
(3) 将第3行改为"k=0;", 将第6行改为"m=m+k;",程序段的输出是( )
答:(1) k=6 m=2 (2) k=6 m=9 (3) k=3 m=6
解析:
(1)
变量 i 的初始值为 0,外层循环条件 i < 2,
外层循环第一次:i = 0,
内层循环 j 的初始值为 0,内层循环条件 j<3,
内层循环第一次:j = 0,满足条件,执行 k++ 后,k 的值为 1。然后执行 j++,j 的值为 1。
内层循环第二次:j = 1,满足条件,执行 k++ 后,k 的值为 2。然后执行 j++,j 的值为 2。
内层循环第三次:j = 2,满足条件,执行 k++ 后,k 的值为 3。然后执行 j++,j 的值为 3。
不满足条件,结束内层循环。
继续向下执行,到 m++,执行后,m 的值为 1。
然后执行 i++,i 的值为 1。
外层循环第二次:i = 1,
内层循环 重新执行 1 次。j 的值从 0 到 3。k 的值累加到 6。然后结束内层循环。继续向下执行,到 m++,执行后,m 的值为 2。然后执行 i++,i 的值为 2。
外层循环也结束了。最终 k 的值为 6,m 的值为 2。
(2) (3) 的分析同 (1) 一样。
8.输出方阵。输入一个正整数 n(1≤n≤10),打印一个 n 行 n 列的方阵。当 n=4 时,输出如下方阵。请填空。
13 14 15 16 9 10 11 12 5 6 7 8 1 2 3 4
int i, j, n; scanf("%d", &n); for (________; i >= 0; ________) { for (j = 1; j <= n; j++) { printf("%4d", ________); } printf("\n"); }
答:i=n-1, i-- , 4*i+j
解析:无。
9.输出等腰三角形。输入一个正整数 n(1≤n≤9),打印一个高度为 n 且由“*”
组成的等腰三角形图案。当 n=3 时,输出如下等腰三角形图案。请填空。
* *** *****
int i, j, n; scanf("%nd", &n); for (i = 1; i <= n; i++) { for (________; ________; ________) { printf(" "); } for (________; ________; ________) { printf("*"); } ________; }
答:j=1;j<=n-i;j++
j=1;j<=2*i-1;j++
printf("\n")
解析:无
10.顺序输出整数的各位数字。输入一个非负整数,从高位开始逐位分割并输出它的各位数字。例如例如,输入9837,输出 9 8 3 7。请填空。
int digit, number, pow, t_number; scanf("%d", &number); t_number = number; pow = 1; while (________) { pow = pow * 10; t_number = t_number / 10; } while (pow >= 1) { digit = ________; number = ________; pow = pow / 10; printf("%d ", digit); } printf("\n");
答:t_number/10!=0 number/pow number%pow
解析:这里先将接收到的 number 的值,复制一份到 t_number 中。
第一个循环中获取的 pow 是为了获取 number的最大的权重(就是最高位的权重值)。比如123,最高位是 1,在百位上,权重就是 100。
第二个循环中,digit 是为了获取每个位上的数字。
三、程序设计题
题目1:求奇数和。输入一批正整数(以零或负数为结束标志),求其中的奇数和。试编写相应程序。
答:
答案代码:
#include <stdio.h> int main() { // 习题(4.3.1) /* 求奇数和。输入一批正整数(以零或负数为结束标志),求其中的奇数和。试编写相应程序。 */ int n, sum; printf("input n:\n"); sum = 0; while (n > 0) { scanf("%d", &n); if (n > 0) { if (n % 2 != 0) { sum += n; // 累加奇数 } } } printf("奇数和为:%d\n", sum); return 0; }
运行结果:
题目2:展开式求和。输入一个实数 x,计算并输出下式的和,直到最后一项的绝对值小于 0.000 01 ,计算结果保留 4 位小数。要求定义和调用函数 fact(n) 计算 n 的阶乘,可以调用 pow() 函数求幂。试编写相应程序。
$$
s=1+x+\frac{x2}{2!}+\frac{x3}{3!}+\frac{x^4}{4!}+...
$$
答:
答案代码:
#include <stdio.h> #include <math.h> double fact(int n); int main() { // 习题(4.3.2) /* 展开式求和。输入一个实数 x,计算并输出下式的和,直到最后一项的绝对值小于 0.000 01 , 计算结果保留 4 位小数。要求定义和调用函数 fact(n) 计算 n 的阶乘,可以调用 pow() 函数求幂。 */ int n; double eps, x, s, item; eps = 0.00001; printf("input x:"); scanf("%lf", &x); s = 0; item = 1; n = 1; while (fabs(item) >= eps) { s += item; item = pow(x, n) / fact(n); n++; } s = s + item; printf("结果为:%.4lf\n", s); return 0; } double fact(int n) { int i; double result = 1; for (i = 1; i <= n; i++) { result *= i; } return result; }
运行结果:
题目3:求序列和。输入一个正整数 n,输出 2/1+3/2+5/3+8/5+... 的前 n 项之和,保留 2 位小数。该序列从第 2 项起,每项的分子是前一项分子与分母的和,分母是前项的分子。试编写相应程序。
答:
答案代码:
#include <stdio.h> int main() { // 习题(4.3.3) /* 求序列和。输入一个正整数 n,输出 2/1+3/2+5/3+8/5+... 的前 n 项之和,保留 2 位小数。 该序列从第 2 项起,每项的分子是前一项分子与分母的和,分母是前项的分子。 */ int n, i, x, x1, x2; double sum; printf("input n:"); scanf("%d", &n); x1 = 1; // 分母 x2 = 2; // 分子 x = x1 + x2; // 临时变量,求分子加分母,为准备下次的分子。 sum = (double)x2 / x1; x1 = x2; for (i = 1; i < n; i++) { x2 = x; sum += (double)x / x1; x = x1 + x; x1 = x2; } printf("sum = %.2lf\n", sum); return 0; }
运行结果:
题目4:和求序列和。输入两个正整数 a 和 n,求 a+aa+aaa+aa...a ( n 个 a ) 之和。例如,输入 2 和 3 ,输出246 ( 2+22+222 )。试编写相应程序。
答:
答案代码:
#include <stdio.h> int main() { // 习题(4.3.4) /* 和求序列和。输入两个正整数 a 和 n,求 a+aa+aaa+aa...a ( n 个 a ) 之和。 例如,输入 2 和 3 ,输出246 ( 2+22+222 )。 */ int n, a, i, sum = 0, result = 0; printf("input a,n:"); scanf("%d%d", &a, &n); for (i = 1; i <= n; i++) { sum += a; result += sum; a = a * 10; } printf("result= %d\n", result); return 0; }
运行结果:
题目5:换硬币。将笔零钱(大于 8 分,小于 1 元,精确到分 ) 换成 5 分,2 分和 1 分的硬币,每种硬币至少有一枚。输入金额,间有几种换法? 针对每种换法, 输出各种面额硬币的数量和硬币的总数量。试编写相应程序。
答:
答案代码:
#include <stdio.h> int main() { // 习题(4.3.5) /* 换硬币。将笔零钱(大于 8 分,小于 1 元,精确到分 ) 换成 5 分,2 分和 1 分的硬币,每种硬币至少有一枚。 输入金额,间有几种换法? 针对每种换法, 输出各种面额硬币的数量和硬币的总数量。 */ int m, n1, n2, n5, total = 0, count = 0; printf("input m:"); scanf("%d", &m); if (m <= 8 || m >= 10) { printf("Invalid!\n"); } else { for (n5 = 1; n5 <= m; n5++) { for (n2 = 1; n2 <= m; n2++) { for (n1 = 1; n1 <= m; n1++) { if (n5 * 5 + n2 * 2 + n1 == m) { count++; printf("5分有 %d 个,2分有 %d 个,1分有 %d 个,总共有 %d 个\n", n5, n2, n1, n5 + n2 + n1); } } } } printf("共有 %d 种算法\n", count); } return 0; }
运行结果:
题目6:输出水仙花数。输入一个正整数 n ( 3≤n≤7 ), 输出所有的 n 位水仙花数。水仙花数是指一个 n 位正整数,它的各位数字的 n 次幕之和等于它本身。 例如 153 的各位数字的立方和是13+53+33 =153。试编写相应程序。
答:
答案代码:
#include <stdio.h> #include <math.h> int main() { // 习题(4.3.6) /* 输出水仙花数。输入一个正整数 n ( 3≤n≤7 ), 输出所有的 n 位水仙花数。 水仙花数是指一个 n 位正整数,它的各位数字的 n 次幕之和等于它本身。 例如 153 的各位数字的立方和是1^3+5^3+3^3 =153。 */ int n; do { printf("input n (3≤n≤7):"); scanf("%d", &n); } while (n > 7 || n < 3); printf("水仙花数有:\n"); int i = pow(10, n) - 1; int limit = 100; int digit, sum, s, m; while (i > 100) // 100-1000 { sum = 0; s = i; // 153 m = n; //循环获取每个位上的数字 while (s != 0) { digit = s / (int)(pow(10, m - 1)); s %= (int)(pow(10, m - 1)); sum += pow(digit, 3); // 每个位上的数字的立方和 m--; } if (sum == i) { printf("%d\t", i); } i--; } printf("\n"); return 0; }
运行结果:
这里说明一下,实际上水仙花数都是指 3 位数,但是此题目要求 3-7 位之间,所以我写答案就没有按照传统的那种求 3 位水仙花数的写法。
题目7:求最大公约数和最小公倍数。输入两个正整数 m 和 n (m≤1000, n≤1000 ),求其最大公约数和最小公倍数。试编写相应程序。
答:
答案代码:
#include <stdio.h> int main() { // 习题(4.3.7) /* 求最大公约数和最小公倍数。输入两个正整数 m 和 n (m≤1000, n≤1000 ),求其最大公约数和最小公倍数。 */ int m, n, i, j; printf("input m,n:"); scanf("%d%d", &m, &n); if (m <= 0 || n <= 0 || m > 1000 || n > 1000) { printf("Invalid!\n"); } for (i = m < n ? m : n; i >= 1; i--) { if (m % i == 0 && n % i == 0) { printf("gcd = %d\n", i); // 最大公约数 break; } } j = m / i * n; printf("lcm = %d\n", j); // 最小公倍数 return 0; }
运行结果:
题目8:高空坠球。 皮球从 heigh ( 来)高度自由落下,触地后反弹到原高度的一半,再落下,再反弹...如此反复。问皮球在第 n 次落地时,在空中一共经过多少距离? 第 n 次反弹的高度是多少 ? 输出保留 1 位小数。试编写相应程序。
答:
答案代码:
#include <stdio.h> #include <math.h> int main() { // 习题(4.3.8) /* 高空坠球。 皮球从 heigh ( 来)高度自由落下,触地后反弹到原高度的一半,再落下,再反弹...如此反复。 问皮球在第 n 次落地时,在空中一共经过多少距离? 第 n 次反弹的高度是多少 ? 输出保留 1 位小数。 */ int i, n; double h, s, x; printf("input h,n:"); scanf("%lf%d", &h, &n); s = h; for (i = 1; i <= n; i++) { x = (double)h / pow(2, n); s += 2 * x; } printf("皮球从 %.1lf 米高度自由落下,第 %d 次落地,在空中共经过 %.1lf 米。第 %d 次反弹高度为 %.1lf 米 \n", h, n, s, n, x); return 0; }
运行结果:
题目9:打印菱形星号 "*"
图案。输入一个正整数 n (n 为奇数),打印一个高度为 n 的 "*"
菱形图案。例如,当 n 为 7 时,打印出以下图案。试编写相应程序。
* * * * * * * * * * * * * * * * * * * * * * * * *
答:
答案代码:
#include <stdio.h> #include <math.h> int main() { // 习题(4.3.9) /* 打印菱形星号 "*" 图案。输入一个正整数 n (n 为奇数),打印一个高度为 n 的 "*" 菱形图案。 例如,当 n 为 7 时,打印出以下图案。 */ int i, j, n, k; printf("input odd number n:"); scanf("%d", &n); k = (n + 1) / 2; // 计算菱形的边长 // 上三角 for (i = 1; i <= k; i++) { for (j = 1; j <= n - 2 * i + 1; j++) // 循环打印空格 { printf(" "); } for (j = 1; j <= 2 * i - 1; j++) { printf("* "); // 循环打印* } printf("\n"); } // 下三角 for (i = n - k; i >= 1; i--) { for (j = 1; j <= n - (2 * i - 1); j++) // 打印空格 { printf(" "); } for (j = 1; j <= 2 * i - 1; j++) { printf("* "); } printf("\n"); } return 0; }
运行结果:
题目10:猴子吃桃问题。一只猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个; 第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半加一个。到第 n 天早上想再吃时,只剩下一个桃子了。问:第一天共摘了多少个桃子? 试编写相应程序。(提示:采取逆向思维的方法,从后往前推断)
答:
答案代码:
#include <stdio.h> int main() { // 习题(4.3.10) /* 猴子吃桃问题。一只猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个; 第二天早上又将剩下的桃子吃掉一半,又多吃了一个。 以后每天早上都吃了前一天剩下的一半加一个。到第 n 天早上想再吃时,只剩下一个桃子了。 问:第一天共摘了多少个桃子? */ int i, n, j, sum = 0; printf("input n:"); scanf("%d", &n); j = 1; // j为第n天的个数,也是第n-1天吃剩下的个数 for (i = 1; i < n; i++) { //循环n天 sum = sum + (j + 1) * 2; //前一天的桃子数(第一天的)=(吃剩下的(第2天的桃子数)+1)*2 } sum = sum + 1; //加上最后一天的1个 printf("第一天摘桃 %d 个\n", sum); return 0; }
运行结果:
题目11:兔子繁衍问题。一对兔子,从出生后第 3 个月起每个月都生一对兔子。小兔子长到第 3 个月后每个月又生一对兔子。假如兔子都不死,请问第 1 个月出生的一对兔子,至少需要繁衔到第几个月时兔子总数才可以达到 n 对? 输入一个不超过10 000的正整数 n ,输出兔子总数达到 n 最少需要的月数。试编写相应程序。
答:
答案代码:
#include <stdio.h> int main() { // 习题(4.3.11) /* 兔子繁衍问题。一对兔子,从出生后第 3 个月起每个月都生一对兔子。 小兔子长到第 3 个月后每个月又生一对兔子。 假如兔子都不死,请问第 1 个月出生的一对兔子,至少需要繁衔到第几个月时兔子总数才可以达到 n 对? 输入一个不超过10 000的正整数 n ,输出兔子总数达到 n 最少需要的月数。 */ int n, m, c; int f1 = 1, f2 = 1; printf("input n (n<=10000):"); scanf("%d", &n); if (n < 2) { printf("想要 %d 对兔子,至少 1 个月,可以产出 1 对兔子 \n", n); } else { m = 2; //月份 c = 0; //当前月的兔子数 while (c < n) { c = f1 + f2; f1 = f2; f2 = c; m++; } printf("想要 %d 对兔子,至少 %d 个月,可以产出 %d 对兔子 \n", n, m, c); } return 0; }
运行结果: