前言:本章详细讲解C语言程序设计第五版谭浩强课后答案 第五章习题答案(3-17题)
3.给两个数m和n输入最大公约数和最小公倍数
最大公约数分为穷举法和辗转相除法
代码如下:
//穷举法.最大公约数
#include<stdio.h>
int main() {
int j = 0;
int m, n, i;
scanf_s("%d %d", &m, &n);
i = m > n ? m : n;
while (!j) {
if (!(m % i) && !(n % i)) {
printf("%d", i);
j++;
}
else i--;
}
return 0;
}
//辗转相除法.最大公约数
#include<stdio.h>
void swap(int x, int y);
int main() {
int m, n, i;
scanf_s("%d %d", &m, &n);
swap(m, n); //把m交换成两者的大值
i = m % n;
while (i) {
m = n;n = i;i = m % n; //辗转相除法核心
}
printf("%d", n);
return 0;
}
void swap(int x, int y) { //交换
int m;
if (x < y) {
m = x; x = y; y = m;
}
return;
}
最小公倍数
//最小公倍数
#include<stdio.h>
int main() {
int count = 0; //计数,输出一个最小公倍数
int m, n, max;
scanf_s("%d %d", &m, &n);
max = m > n ? m : n; //找出两者中的最大值,记为max
while (!count) {
if (!(max % m) && !(max % n)) {
printf("%d", max);
count++;
}
else max++;
}
return 0;
}
4.输入一行字符,分别统计出其中英文字母,空格,数字和其它字符
#include<stdio.h>
int main() {
char c;
int english = 0, space = 0, number = 0, other = 0;
while ((c = getchar()) != '\n') {
if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'z')
english++;
else if (c == ' ')
space++;
else if (c >= '0' && c <= '9')
number++;
else other++;
}
printf("%d %d %d %d", english, space, number, other);
return 0;
}
6.求1!+2!+3!+...+20! //累乘思想
#include<stdio.h>
int main() {
double p = 1,sum = 0; //不应定义为int或者long(不能容纳所求得的结果)
for (int i = 1; i <= 20; i++) {
p *= i; //每项阶乘的值
sum += p;
}
printf("%22.15e\n", sum); //控制精度
return 0;
}
5.求Sn=a+aa+aaa+...+aaa...aaa之值,其中a是一个数字,n表示a的位数,n由键盘输入
#include<stdio.h>
int main() {
int w[1000] = { 0 }; //储存a,aa,aaa每个数的值
int number = 0,sum=0; //number为每个数的值,sum为Sn
int a, n; //a是一个数字,n表示a的位数
scanf_s("%d %d", &a, &n);
for (int i = 1,count=1;count<=n; i *= 10) {
number += a*i;
w[count] = number;
sum += w[count];
count++;
} //采用简单粗暴算法,aaa=a*100+a*10+a
printf("%d", sum);
return 0;
}
上面那个太麻烦了,下面是改进
#include<stdio.h>
int main() {
int a,n;
int sum = 0,p=0;
scanf("%d %d" ,& a,&n);
for (int i = 1; i <= n; i++) {
p = a+p * 10; //每一项的值
sum += p; //求和
}
printf("%d", sum);
return 0;
}
7.k:1-100,k*k:1-50,1/k:1-10,求三者的和
#include<stdio.h>
#include<math.h>
int main() {
double sum = 0.0;
for (int k = 1; k < 101; k++) {
sum += k;
}
for (int k = 1; k < 51; k++) {
sum += pow(k,2); //表示k*k
}
for (double k = 1.0; k < 11; k++) {
sum += 1.0 / k;
}
printf("%f", sum);
return 0;
}
改进
//用了3个for,时间空间复杂度较大,改进:一个for循环中加入两个if判断
#include<stdio.h>
#include<math.h>
int main() {
double sum1 = 0.0,sum2=0.0,sum3=0.0;
for (int k = 1; k < 101; k++) {
sum1 += k;
if (k < 51) sum2 += pow(k, 2); //表示k*k
if (k < 11) sum3+= 1.0 / k;
}
printf("%f", sum1+sum2+sum3);
return 0;
}
8.输出所有的水仙花数
#include<stdio.h>
#include<math.h>
int main() {
int a, b, c;
for (int x = 100; x < 1000; x++) {
a = x / 100; //百位
b = x % 100 / 10; //十位
c = x % 10; //个位
if (x == pow(a, 3) + pow(b, 3) + pow(c, 3))
printf("%d\t", x);
}
return 0;
} //遍历
9.一个数如果恰好等于它的因子之和,这个数就称为完数。
例如,6的英子为1,2,3,而6=1+2+3,因此6是完数,编程
找出1000之内的所有完数,并按照6 its factors are 1,2,3
#include<stdio.h>
int main() {
int num, sum, factor;//数,和,因子
for (num = 2; num <= 1000; num++) {
sum = 1; //1是所有数的因子
for (factor = 2; factor <= num / 2; factor++) {
if (num % factor == 0) sum += factor;
}
if (sum == num) {
printf("%d its factor are ", num);
for (factor = 2; factor <= num / 2; factor++) {
if (num % factor == 0)
printf("%d,", factor);
}//如果因子和等于该数,则求出该数每一个因子并输出
printf("\n");
}
}
return 0;
}
10.有一个分数序列:2/1,3/2,5/3,8/5,13/8,21/13,...
#include<stdio.h>
int main() {
int n; //该分式的项数
double p = 0, sum = 0, x = 1, y = 2, t = 0;
scanf_s("%d", &n);
for (int i = 1; i <= n; i++) {
p = y / x; //该分式每一项的值
sum += p; //该分式的和
t = x; //存储x的值
x = y; //上一项的分子为下一项的分母
y += t; //下一项的分子为上一项的分子与分母的和
}
printf("%f", sum);
return 0;
}
11.有一个球从100米高度自由下落,每次落地后又反弹回原来高度的一半,再落下,再反弹,求它在第十次落地时共经历多少米,第十次反弹多高
#include<stdio.h>
#include<math.h>
int main() {
double n = 100.0, sum = 100.0, every = 0.0;//sum为小球总经历高度,every为小球每次回弹高度
for (int i = 1; i <= 10; i++) {
every = pow(0.5, i) * n; //(1/2)^i*100代表第i次下落回弹的高度
sum += pow(0.5, i) * n * 2; //除第一次,其余九次上+下共两次
}
printf("%f %f", sum, every);
return 0;
}
12.猴子吃桃问题。猴子第1天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。第2天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,就只剩一个桃子了。求第1天共摘多少个桃子
#include<stdio.h>
int main() {
int n = 1; //第十天的桃子数
for (int i = 2; i <= 10; i++)
n = (n + 1) * 2; //后一天的桃子数+1再乘以2等于前一天的桃子数
printf("%d", n);
return 0;
}
13.用迭代法求x=根号a,求平方根的迭代公式为:
Xn+1=1/2*(Xn+a/Xn):要求前后两次求出的x的差的绝对值小于10^(-5)
#include<stdio.h>
#include<math.h>
int main() {
float a, x0, x1;
scanf_s("%f", &a);
x0 = a / 2; //x0自己赋初值
x1 = (x0 + a / x0) / 2;
do {
x0 = x1;
x1 = (x0 + a / x0) / 2; //替换思想
} while (fabs(x0 - x1) >= 1e-5);
printf("sqrt(a)=%f", x1);
return 0;
}
14.用牛顿迭代法求下面方程在1.5附近的根:
2x^3-4x^2+3x-6=0 注:牛顿迭代法公式为:Xn + 1 = Xn - f(n) / f'(n) Xn为输出值,本题为1.5,f(n)=2x^3-4x^2+3x-6,f'(n)=6x^2-8x+3
#include<stdio.h>
#include<math.h>
int main() {
double x0, x1, f, f1;
x1 = 1.5;
do {
x0 = x1;
f = 2 * pow(x0, 3) - 4 * pow(x0, 2) + 3 * x0 - 6;
f1 = 6 * pow(x0, 2) - 8 * x0 + 3;
x1 = x0 - f / f1;
} while (fabs(x1 - x0) >= 1e-5);
printf("方程在1.5附近的根为:%f\n", x1);
return 0;
}
15.用二分法求下面方程在(-10,10)的根:2x^3-4x^2+3x-6=0
#include<stdio.h>
#include<math.h>
int main() {
double left = -10.0, right = 10.0, result=1.0, mid=0.0;
while (fabs(result) > 1e-5) {
mid = (left + right) / 2;
result = 2 * pow(mid, 3) - 4 * pow(mid, 2) + 3 * mid - 6;
if (result > 0) right = mid;
else left = mid;
}
printf("该方程的根为:%f", mid);
return 0;
}//一直在中间找
16.输出以下图形
#include<stdio.h>
int main() {
for (int i = 0; i <= 3; i++){
for (int j = 0; j <= 3 - i; j++)
printf(" ");
for (int k = 0; k <= 2*i; k++) //始于0终于2的倍数,对应*数为奇数
printf("*");
printf("\n");
}
for (int i = 0; i <= 2; i++) {
for (int j = 0; j <= i + 1; j++)
printf(" ");
for (int k = 0; k <= 4 - 2 * i; k++)
printf("*");
printf("\n");
}
return 0;
}
17.两个乒乓球队进行比赛,各出3人。甲队为A,B,C三人,乙对为X,Y,Z三人。已抽签决定比赛名单。有人向队员打听比赛的名单,A说他不和X比,C说他不和X,Z比,请编程序找出3队赛手的名单