c程式設計第五版課後答案譚浩強
1.請畫出例5.6中給出的3個程式段的流程圖

流程圖1:
流程圖2:
流程圖3:
2.請補充例5. 7程式,分别統計當“fabs(t)>= le- 6”和“fabs(t)> = le- 8”時執行循環體的次數。
fabs(t)>= le- 6 ,示例代碼
# include <stdio.h>
# include <math.h>
int main()
{
int sign = 1;
double pi = 0.0, term = 1.0;
int n = 0;
while (fabs(term) >= 1e-6)
{
n++;
term = 1.0 / (2 * n - 1)*sign;
pi += term;
sign = -sign;
}
pi *= 4;
printf("pi的近似值是%lf\n", pi);
printf("循環體循環了%d次\n", n);
return 0;
}
運作截圖:
fabs(t)> = le- 8,示例代碼
# include <stdio.h>
# include <math.h>
int main()
{
int sign = 1;
double pi = 0.0, term = 1.0;
int n = 0;
while (fabs(term) >= 1e-8)
{
n++;
term = 1.0 / (2 * n - 1)*sign;
pi += term;
sign = -sign;
}
pi *= 4;
printf("pi的近似值是%lf\n", pi);
printf("循環體循環了%d次\n", n);
return 0;
}
運作截圖:
3.輸人兩個正整數m和n,求其最大公約數和最小公倍數
答案解析:
該題題目直接使用“輾轉相除法”來求解最大公約數,以除數和餘數反複做除法運算,當餘數為 0 時,就取得目前算式除數為最大公約數。
最大公約數和最小公倍數之間的性質:兩個自然數的乘積等于這兩個自然數的最大公約數和最小公倍數的乘積。是以,當我們求出最大公約數,就可以很輕松的求出最小公倍數。
代碼示例:
#include <stdio.h>
int main()
{
int p, r, n, m, temp;
printf("請輸入兩個正整數n,m:");
scanf("%d%d,", &n, &m);
//調整n儲存較大的值
if (n < m)
{
temp = n;
n = m;
m = temp;
}
p = n * m;
while (m != 0)
{
r = n % m;
n = m;
m = r;
}
printf("它們的最大公約數為:%d\n", n);
printf("它們的最小公倍數為:%d\n", p / n);
return 0;
}
運作截圖:
4.輸人一行字元,分别統計出其中英文字母、空格、數字和其他字元的個數。
答案解析:
該題可以調用
getchar
函數,從stdin流中讀入一個字元,當輸入多個字元時,getchar()再執行時就會直接從緩沖區中讀取了。等同于
getc(stdin)
。是以,我們循環調用getchar,直到将标準輸入的内容讀到換行符
\n
為止。同時判斷,讀取到的字元是英文字母、空格、數字或者其他字元,并計數;
代碼示例:
#include <stdio.h>
int main()
{
char c;
//定義eng_char為英文字母的個數,初始值為0
//定義space_char為空格字元的個數,初始值為0
//定義digit_char為數字字元的個數,初始值為0
//定義other_char為其他字元的個數,初始值為0
int eng_char = 0, space_char = 0, digit_char = 0, other_char = 0;
printf("請輸入一行字元:");
while ((c = getchar()) != '\n')
{
if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
{
eng_char++;
}
else if (c == ' ')
{
space_char++;
}
else if (c >= '0' && c <= '9')
{
digit_char++;
}
else
{
other_char++;
}
}
printf("英文字母數量:%d\n空格數量:%d\n數字數量:%d\n其他字元數量:%d\n", eng_char, space_char, digit_char, other_char);
return 0;
}
運作截圖:
5.求 S n S_n Sn=a+aa+aaa+…+ a a + ⋯ + a ⏞ n 個 a \overbrace{aa+\dots+a}^{n個a} aa+⋯+a
n個a 之值,其中a是一個數字,n表示a的位數,n由鍵盤輸入。例如:
2+22+222+2222+22222 (此時n=5)
答案解析:
該題目可以将數字拆分為
a * 10^n + 前一個數字
,例如:
2 = 2 * 10^0 + 0
: 預設2的前一個數字為0,也就是沒有任何值
22 = 2 * 10^1 + 2
: 22的前一個數字為2
222 = 2*10^2 + 22
:222的前一個數字為22
以此類推…
是以,在每次循環的時候,需要儲存下,上一次結果的值,友善下一次計算
還需要使用到C庫當中使用的pow函數,來計算某個數的n次方,我們在該題目當中使用的是10的n次方,n随着循環的次數,以此遞增。
代碼示例:
#include <stdio.h>
#include <math.h>
int main()
{
//n為a的個數
int n;
double a, prev_sum = 0.0, total_sum = 0.0;
printf("請輸入a的值以及n的值: ");
scanf("%lf %d", &a, &n);
//循環n次求總和
for (int i = 0; i < n; i++)
{
prev_sum += a * pow(10, i);
total_sum += prev_sum;
}
printf("總和為:%lf\n", total_sum);
return 0;
}
運作截圖:
6.求 ∑ n = 1 20 n ! \sum\limits_{n=1}^{20}n! n=1∑20n! (即求1!+2!+3!+4!+…+20!)。
答案解析:
該題需要從1循環到20,依次求出每一個數字階乘的結果。是以在代碼當中需要有兩個循環,大循環從1到20,保證1到20個數字都被循環到,小循環裡計算N階乘,累加求和。注意:對于20的階乘已經超出了
int
類型能過表示的數字範圍,是以在代碼當中使用
double
類型
代碼示例:
#include<stdio.h>
int main()
{
double total_sum = 0;
for(int i = 1; i <= 20; i++)
{
double single_sum = 1;
for (int j = i; j > 0; j--)
{
single_sum *= j;
}
total_sum += single_sum;
}
printf("1~20每個數字階乘總和為:%lf\n",total_sum);
return 0;
}
運作截圖:
7. ∑ k = 1 100 k \sum\limits_{k=1}^{100}k k=1∑100k + ∑ k = 1 50 k 2 \sum\limits_{k=1}^{50}{k}^2 k=1∑50k2 + ∑ k = 1 10 1 k \sum\limits_{k=1}^{10}{\frac{1}{k}} k=1∑10k1 。
答案解析:
對于 ∑ k = 1 100 k \sum\limits_{k=1}^{100}k k=1∑100k而言,指的是求從1到100的和。每個數字為整數,求和也為整數
對于 ∑ k = 1 50 k 2 \sum\limits_{k=1}^{50}{k}^2 k=1∑50k2而言,指的是求從12到502的和。每個數字為整數,求和也為整數。
對于 ∑ k = 1 10 1 k \sum\limits_{k=1}^{10}{\frac{1}{k}} k=1∑10k1而言,指的是求從 1 1 \frac{1}{1} 11到 1 10 \frac{1}{10} 101的和。每個數字不是整數,求和也不是整數。
綜上所述:求和結果不是整數,是以定義求和變量是需要定義為帶有精度的變量
double
該題目,最大的求和是從從1到100,是以需要一個循環,從1周遊到100。針對第一種情況,則周遊100次停下來。針對第二種情況,則周遊50次的時候停下來,針對第三種情況,則周遊10遍就停下來。
最後,在周遊每一個數字的時候,針對三種不同的情況求和。最後将三種不同請求的和加起來就是總體的和
代碼示例:
#include <stdio.h>
int main()
{
double total_sum = 0, sum1 = 0, sum2 = 0, sum3 = 0.0;
for (int k = 1; k <= 100; k++)
{
sum1 += k;
//周遊50次就不在執行情況2
if (k <= 50)
{
sum2 += k * k;
}
//周遊10次就不在執行情況3
if (k <= 10)
{
sum3 += 1.0 / k;
}
}
total_sum = sum1 + sum2 + sum3;
printf("三種情況求和結果為:%lf\n", total_sum);
return 0;
}
運作截圖:
![## c語言程式設計第五版課後答案譚浩強
1.請畫出例5.6中給出的3個程式段的流程圖
流程圖1:
流程圖2:
流程圖3:
2.請補充例5. 7程式,分别統計當“fabs(t)>= le- 6”和“fabs(t)> = le- 8”時執行循環體的次數。
fabs(t)>= le- 6 ,示例代碼
# include <stdio.h>
# include <math.h>
int main()
{
int sign = 1;
double pi = 0.0, term = 1.0;
int n = 0;
while (fabs(term) >= 1e-6)
{
n++;
term = 1.0 / (2 * n - 1)*sign;
pi += term;
sign = -sign;
}
pi *= 4;
printf("pi的近似值是%lf\n", pi);
printf("循環體循環了%d次\n", n);
return 0;
}
運作截圖:
fabs(t)> = le- 8,示例代碼
# include <stdio.h>
# include <math.h>
int main()
{
int sign = 1;
double pi = 0.0, term = 1.0;
int n = 0;
while (fabs(term) >= 1e-8)
{
n++;
term = 1.0 / (2 * n - 1)*sign;
pi += term;
sign = -sign;
}
pi *= 4;
printf("pi的近似值是%lf\n", pi);
printf("循環體循環了%d次\n", n);
return 0;
}
運作截圖:
3.輸人兩個正整數m和n,求其最大公約數和最小公倍數
答案解析:
該題題目直接使用“輾轉相除法”來求解最大公約數,以除數和餘數反複做除法運算,當餘數為 0 時,就取得目前算式除數為最大公約數。
最大公約數和最小公倍數之間的性質:兩個自然數的乘積等于這兩個自然數的最大公約數和最小公倍數的乘積。是以,當我們求出最大公約數,就可以很輕松的求出最小公倍數。
代碼示例:
#include <stdio.h>
int main()
{
int p, r, n, m, temp;
printf("請輸入兩個正整數n,m:");
scanf("%d%d,", &n, &m);
//調整n儲存較大的值
if (n < m)
{
temp = n;
n = m;
m = temp;
}
p = n * m;
while (m != 0)
{
r = n % m;
n = m;
m = r;
}
printf("它們的最大公約數為:%d\n", n);
printf("它們的最小公倍數為:%d\n", p / n);
return 0;
}
運作截圖:
4.輸人一行字元,分别統計出其中英文字母、空格、數字和其他字元的個數。
答案解析:
該題可以調用
getchar
函數,從stdin流中讀入一個字元,當輸入多個字元時,getchar()再執行時就會直接從緩沖區中讀取了。等同于
getc(stdin)
。是以,我們循環調用getchar,直到将标準輸入的内容讀到換行符
\n
為止。同時判斷,讀取到的字元是英文字母、空格、數字或者其他字元,并計數;
代碼示例:
#include <stdio.h>
int main()
{
char c;
//定義eng_char為英文字母的個數,初始值為0
//定義space_char為空格字元的個數,初始值為0
//定義digit_char為數字字元的個數,初始值為0
//定義other_char為其他字元的個數,初始值為0
int eng_char = 0, space_char = 0, digit_char = 0, other_char = 0;
printf("請輸入一行字元:");
while ((c = getchar()) != '\n')
{
if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
{
eng_char++;
}
else if (c == ' ')
{
space_char++;
}
else if (c >= '0' && c <= '9')
{
digit_char++;
}
else
{
other_char++;
}
}
printf("英文字母數量:%d\n空格數量:%d\n數字數量:%d\n其他字元數量:%d\n", eng_char, space_char, digit_char, other_char);
return 0;
}
運作截圖:
5.求 S n S_n Sn=a+aa+aaa+…+ a a + ⋯ + a ⏞ n 個 a \overbrace{aa+\dots+a}^{n個a} aa+⋯+a
n個a 之值,其中a是一個數字,n表示a的位數,n由鍵盤輸入。例如:
2+22+222+2222+22222 (此時n=5)
答案解析:
該題目可以将數字拆分為
a * 10^n + 前一個數字
,例如:
2 = 2 * 10^0 + 0
: 預設2的前一個數字為0,也就是沒有任何值
22 = 2 * 10^1 + 2
: 22的前一個數字為2
222 = 2*10^2 + 22
:222的前一個數字為22
以此類推…
是以,在每次循環的時候,需要儲存下,上一次結果的值,友善下一次計算
還需要使用到C庫當中使用的pow函數,來計算某個數的n次方,我們在該題目當中使用的是10的n次方,n随着循環的次數,以此遞增。
代碼示例:
#include <stdio.h>
#include <math.h>
int main()
{
//n為a的個數
int n;
double a, prev_sum = 0.0, total_sum = 0.0;
printf("請輸入a的值以及n的值: ");
scanf("%lf %d", &a, &n);
//循環n次求總和
for (int i = 0; i < n; i++)
{
prev_sum += a * pow(10, i);
total_sum += prev_sum;
}
printf("總和為:%lf\n", total_sum);
return 0;
}
運作截圖:
6.求 ∑ n = 1 20 n ! \sum\limits_{n=1}^{20}n! n=1∑20n! (即求1!+2!+3!+4!+…+20!)。
答案解析:
該題需要從1循環到20,依次求出每一個數字階乘的結果。是以在代碼當中需要有兩個循環,大循環從1到20,保證1到20個數字都被循環到,小循環裡計算N階乘,累加求和。注意:對于20的階乘已經超出了
int
類型能過表示的數字範圍,是以在代碼當中使用
double
類型
代碼示例:
#include<stdio.h>
int main()
{
double total_sum = 0;
for(int i = 1; i <= 20; i++)
{
double single_sum = 1;
for (int j = i; j > 0; j--)
{
single_sum *= j;
}
total_sum += single_sum;
}
printf("1~20每個數字階乘總和為:%lf\n",total_sum);
return 0;
}
運作截圖:
7. ∑ k = 1 100 k \sum\limits_{k=1}^{100}k k=1∑100k + ∑ k = 1 50 k 2 \sum\limits_{k=1}^{50}{k}^2 k=1∑50k2 + ∑ k = 1 10 1 k \sum\limits_{k=1}^{10}{\frac{1}{k}} k=1∑10k1 。
答案解析:
對于 ∑ k = 1 100 k \sum\limits_{k=1}^{100}k k=1∑100k而言,指的是求從1到100的和。每個數字為整數,求和也為整數
對于 ∑ k = 1 50 k 2 \sum\limits_{k=1}^{50}{k}^2 k=1∑50k2而言,指的是求從12到502的和。每個數字為整數,求和也為整數。
對于 ∑ k = 1 10 1 k \sum\limits_{k=1}^{10}{\frac{1}{k}} k=1∑10k1而言,指的是求從 1 1 \frac{1}{1} 11到 1 10 \frac{1}{10} 101的和。每個數字不是整數,求和也不是整數。
綜上所述:求和結果不是整數,是以定義求和變量是需要定義為帶有精度的變量
double
該題目,最大的求和是從從1到100,是以需要一個循環,從1周遊到100。針對第一種情況,則周遊100次停下來。針對第二種情況,則周遊50次的時候停下來,針對第三種情況,則周遊10遍就停下來。
最後,在周遊每一個數字的時候,針對三種不同的情況求和。最後将三種不同請求的和加起來就是總體的和
代碼示例:
#include <stdio.h>
int main()
{
double total_sum = 0, sum1 = 0, sum2 = 0, sum3 = 0.0;
for (int k = 1; k <= 100; k++)
{
sum1 += k;
//周遊50次就不在執行情況2
if (k <= 50)
{
sum2 += k * k;
}
//周遊10次就不在執行情況3
if (k <= 10)
{
sum3 += 1.0 / k;
}
}
total_sum = sum1 + sum2 + sum3;
printf("三種情況求和結果為:%lf\n", total_sum);
return 0;
}
運作截圖:
8.輸出所有的“水仙花數”,所謂“水仙花數”是指一個3位數,其各位數字立方和等于該數本身。例如,153是水仙花數,因為153=1*+5*+3。
答案解析:
從題目當中得到”水仙花數“為一個3位數,則範圍确定為[100, 999]。另外需要擷取該數字的百位數字,十位數字,個位數字相加起來等于該數本身,則我們需要使用到
%
除的方式,來擷取每一個位權的數字。
代碼示例:
#include <stdio.h>
int main()
{
//a表示百位數字,b表示十位數字,c表示各位數字
int a, b, c;
for (int i = 100; i <= 999; i++)
{
a = i / 100;
b = (i / 10) % 10;
c = i % 10;
if (a * a * a + b * b * b + c * c * c == i)
{
printf("%d\n", i);
}
}
return 0;
}
運作截圖:
9.一個數如果恰好等于它的因子之和,這個數就稱為“完數”。例如,6的因子為1,2,3,而6=1+2+3,是以6是“完數”。程式設計式找出1000之内的所有完數,并按下面格式輸出其因子:
6 its factors are 1,2,3
答案解析:
因子:整數a除以整數b(b≠0) 的商正好是整數而沒有餘數,我們就說b是a的因子。整數n除以m,結果是無餘數的整數,那麼我們稱m就是n的因子。 需要注意的是,唯有被除數,除數,商皆為整數,餘數為零時,此關系才成立。因子是不包括自身的
舉一個例子:20 = 4 * 5,則4和5就是20的因子,也被稱之為因子
代碼示例:
#include<stdio.h>
int main()
{
int data, fator, sum; /* data表示要判斷的數,fator表示因子,sum表示因子之和*/
for (data = 2; data <= 1000; data++)
{
//1是所有整數的因子,是以因子之和從1開始
sum = 1;
for (fator = 2; fator <= data / 2; fator++)
{
/* 判斷data能否被fator整除,能的話fator即為因子 因子不包括自身 */
if (data % fator == 0)
{
sum += fator;
}
}
// 判斷此數是否等于因子之和 */
if (sum == data)
{
printf("%d its factors are 1, ", data);
for (fator = 2; fator <= data / 2; fator++)
{
if (data % fator == 0)
{
printf("%d, ", fator);
}
}
printf("\n");
}
}
return 0;
}
運作截圖:
10.有一個分數序列,求出這個數列的前20項之和。
2 1 \frac{2}{1} 12, 3 2 \frac{3}{2} 23, 5 3 \frac{5}{3} 35, 8 5 \frac{8}{5} 58, 13 8 \frac{13}{8} 813, 25 13 \frac{25}{13} 1325,…
答案解析:
從題目當中可以看出來,下一個分式當中的分子為上一個分式中分子和分母的和,分母為上一個分式的分子。通過這個規律不難推出下一個分式的分子和分母,需要注意的是,儲存分式的結果不能使用到整數,因為有可能會有小數的存在,是以我們需要選用浮點數
double
代碼示例:
#include <stdio.h>
//定義循環次數
#define COUNT 20
int main()
{
//定義第一個分式的分子為a, 值為2; 定義分母為b,值為1
//定義相加的和為sum,初始值為0
double a = 2, b = 1, sum = 0;
double temp;
for (int i = 0; i < COUNT; i++)
{
sum += a / b;
//記錄前一項分子
temp = a;
//前一項分子與分母之和為後一項分子
a = a + b;
//前一項分子為後一項分母
b = temp;
}
printf("前%d項之和為:sum=%9.7f\n", COUNT, sum);
return 0;
}
運作截圖:
11.一個球從100m高度自由落下,每次落地後反彈回原高度的一半,再落下,再反彈。求它在第10次落地時共經過多少米,第10次反彈多高。
答案解析:
該題目需要循環10次,在每一循環的時候,需要将下落的高度和回彈的高度加起來。需要注意的點,第10次下落不需要在計算回彈的距離了,是以需要特殊處理下。在計算每次高度的時候,會有小數存在,是以需要選用浮點數
代碼示例:
#include <stdio.h>
int main()
{
//總高度
double total_m = 100.0;
//小球經曆的米數
double total_sum = 0.0;
for (int i = 0; i < 10; i++)
{
total_sum += total_m;
total_m /= 2;
total_sum += total_m;
}
//不需要計算第10次的反彈高度,是以減去
total_sum -= total_m;
printf("小球總共經曆%lf米, 第10次反彈%lf米\n", total_sum, total_m);
return 0;
}
運作截圖:
12.猴子吃桃問題。猴子第1天摘下若幹個桃子,當即吃了一半,還不過瘾,又多吃了一個。第2天早上又将剩下的桃子吃掉一半,又多吃了一個。以後每天早上都吃了前一天剩下的一半零一個。到第10天早上想再吃時,就隻剩一個桃子了。求第1天共摘多少個桃子。
答案解析:
從題面上來看,可以推出,後一天的桃子數量 = 前一天桃子數量 / 2 - 1。是以,該公式也可以寫成前一天的桃子數量 = (後一天桃子數量+1) * 2。是以我們知道了第10天剩餘桃子的數量,則可以依次推算出桃子的前一天桃子的總數。需要注意的點,猴子隻是吃了9天,是以,我們隻需要周遊9次就可以了。
代碼示例:
#include <stdio.h>
int main()
{
int day = 9;
int prev_day_count;
int cur_day_count = 1;
while (day > 0)
{
prev_day_count = (cur_day_count + 1) * 2;
cur_day_count = prev_day_count;
day--;
}
printf("total count : %d\n", cur_day_count);
return 0;
}
運作截圖:
13.用疊代法求x= a \sqrt{a} a
。求平方根的疊代公式為
x n + 1 x_{n+1} xn+1 = 1 2 \frac{1}{2} 21( x n x_{n} xn + a x n \frac{a}{x_n} xna)
要求前後兩次求出的x的差的絕對值小于 1 0 − 5 10^{-5} 10−5。
答案解析:
題面上已經告訴兩條資訊,一個是x= a \sqrt{a} a
,是以我們可以通過a求出x的值。另外一條是 x n + 1 x_{n+1} xn+1 = 1 2 \frac{1}{2} 21( x n x_{n} xn + a x n \frac{a}{x_n} xna),可以通過x的值求出 x n + 1 x_{n+1} xn+1的值,是以,隻需要輪詢的計算,不斷的計算內插補點,直到滿足內插補點小于 1 0 − 5 10^{-5} 10−5就可以停止了
代碼示例:
#include <stdio.h>
#include <math.h>
int main()
{
float a, x0, x1;
printf("請輸入一個正數: ");
scanf("%f", &a);
x0 = a / 2;
x1 = (x0 + a / x0) / 2;
do
{
x0 = x1;
x1 = (x0 + a / x0) / 2;
} while (fabs(x0 - x1) >= 1e-5);
printf("[%f] 的平方根為 [%f]\n", a, x1);
return 0;
}
運作截圖:
14.用牛頓疊代法求下面方程在1.5附近的根:
2 x 3 x^3 x3- 4 x 2 x^2 x2 + 3 x x x - 6= 0
答案解析:
牛頓疊代法的公式為:
x n + 1 x_{n+1} xn+1 = x n x_{n} xn - f ( x n ) f ′ ( x n ) \frac{f(x_{n})}{f'(x_{n})} f′(xn)f(xn)
其中, x n x_{n} xn為輸出的值,在該題目當中為1.5。 f ( x n ) f(x_{n}) f(xn)為公式2 x 3 x^3 x3- 4 x 2 x^2 x2 + 3 x x x - 6。 f ′ ( x n ) f'(x_{n}) f′(xn)為導數,根據導數原則:
規則1: x n x^n xn = n * x ( n − 1 ) x^{(n-1)} x(n−1), 規則2:常數的導數為0。可以推導出 f ′ ( x n ) f'(x_{n}) f′(xn) = 6 x 2 x^2 x2 - 8x + 3。
在依照牛頓疊代法計算出 x n + 1 x_{n+1} xn+1的值,直到求出的內插補點小于0.00001
代碼示例:
#include <stdio.h>
#include <math.h>
int main()
{
double x1, x0, f, f1;
x1 = 1.5;
do
{
x0 = x1;
f = ((2 * x0 - 4) * x0 + 3) * x0 - 6;
f1 = (6 * x0 - 8) * x0 + 3;
x1 = x0 - f / f1;
} while (fabs(x1 - x0) >= 1e-5);
printf("方程在1.5附近的根為:%lf\n", x1);
return 0;
}
運作截圖:
15.用二分法求下面方程在(-10,10)的根:
2 x 3 x^3 x3- 4 x 2 x^2 x2 + 3 x x x - 6= 0
答案解析:
将區間劃分為兩部分,記錄區間左右端點,得到中點。每次運算将中點帶入方程進行運算,求得結果,進行分析:
結果 > 0:将中位數指派給右端點
結果 < 0:将中位數指派給左端點
以此類推…
fabs函數是一個求絕對值的函數,求出x的絕對值,和數學上的概念相同;
le-5: 1 0 − 5 10^{-5} 10−5,即0.00001
代碼示例:
#include<stdio.h>
#include<math.h>
int main()
{
double left = -10, right = 10, mid;
double temp = 10;
while (fabs(temp) > 1e-5)
{
mid = (left + right) / 2;
//((2x - 4)*x + 3) * x - 6 ==> 2x^3 - 4x^2 + 3x -6
temp = ((2 * mid - 4) * mid + 3) * mid - 6;
if (temp > 0)
{
right = mid;
}
else if (temp < 0)
{
left = mid;
}
}
printf("在(-10,10)的根為:%lf", mid);
return 0;
}
運作截圖:
16.輸出以下圖案:
*
***
*****
*******
*****
***
*
答案解析:
該題目需要關心目前行對應的從最左邊到第一顆
*
的空格數量以及星星數量。将該題分為兩個部分,前面4行和後面3行來進行拆分。
前4行中:
第一行:行号為0, 空格數為3,星星數量為1;
第二行:行号為1, 空格數為2, 星星數量為3;
第三行:行号為2, 空格數為1, 星星數量為5;
第四行:行号為3, 空格數為0,星星數量為7;
則我們可以推出兩組關系,即行号和空格數量關系為:空格數 = 3 - 行号 。行号與星星的關系為:星星數 = 2 * 行号 + 1
後三行中:
第一行:行号為0,空格數為1,星星數量為5;
第二行:行号為1, 空格數為2, 星星數量為3;
第三行:行号為2, 空格數為3,星星數量為1;
則我們推出兩組關系,即行号與數量的關系:空格數 = 行号 + 1。行号與星星的關系:星星數 = 7 - 2 * (行号+1)
基于上面的關系,我們寫出如下代碼:
代碼示例:
#include <stdio.h>
int main()
{
int cur_row, space_count, start_count;
//輸出前4行内容
for (cur_row = 0; cur_row < 4; cur_row++)
{
//計算目前行空格數量,并且進行列印
for (space_count = 3 - cur_row; space_count > 0; space_count--)
{
printf(" ");
}
//計算目前行*數量,并且進行列印
for (start_count = 2 * cur_row + 1; start_count > 0; start_count--)
{
printf("*");
}
printf("\n") ;
}
//輸出後三行
for (cur_row = 0; cur_row < 3; cur_row++)
{
for (space_count = cur_row + 1; space_count > 0; space_count--)
{
printf(" ");
}
for (start_count = 7 - 2 * (cur_row + 1); start_count > 0; start_count--)
{
printf("*");
}
printf("\n");
}
return 0;
}
運作截圖:
17.兩個乒乓球隊進行比賽,各出3人。甲隊為A,B,C 3人,乙隊為X,Y,Z 3人。已抽簽決定比賽名單。有人向隊員打聽比賽的名單,A說他不和X比,C說他不和X,Z比,請程式設計式找出3對賽手的名單。
答案解析:
從題面上得知,每隊為3人,則隐含條件為隊内三人是不能比賽的,并且A一定不會和X比,C一定不會X和Z比;則我們不難寫出判斷條件:
如果A和X比 或者 C和X比 或者 C和Z比 或者 A和B比 或者 A和C比 或者 B和C比,都是不可以的;是以我們隻要窮舉A比賽對象,B比賽對象,C比賽對象,判斷上述條件就可以了;
代碼示例:
#include <stdio.h>
int main()
{
int A_battle, B_battle, C_battle;
//如果A對戰的對象從“X”到“Z”
for (A_battle = 'X'; A_battle <= 'Z'; A_battle++)
{
//如果B對戰的對象從“X”到“Z”
for (B_battle = 'X'; B_battle <= 'Z'; B_battle++)
{
//如果C對戰的對象從“X”到“Z”
for (C_battle = 'X'; C_battle <= 'Z'; C_battle++)
{
//去除限制條件
if (A_battle == 'X' || C_battle == 'X' || C_battle == 'Z' || B_battle == A_battle || B_battle == C_battle || A_battle == C_battle)
{
continue;
}
printf("A對%c,B對%c,C對%c", A_battle, B_battle, C_battle);
}
}
}
return 0;
}
運作截圖:
c語言程式設計第五版課後答案譚浩強更多答案
c語言程式設計第五版課後答案譚浩強 第四章課後答案
c語言程式設計第五版課後答案譚浩強 第六章課後答案
](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9pbWcyMDIwLmNuYmxvZ3MuY29tL2Jsb2cvMjA0ODE1NS8yMDIwMDYvMjA0ODE1NS0yMDIwMDYzMDExNTMyOTIzOS04MDY2MzM3NTcucG5n?x-oss-process=image/format,png)
8.輸出所有的“水仙花數”,所謂“水仙花數”是指一個3位數,其各位數字立方和等于該數本身。例如,153是水仙花數,因為153=1*+5*+3。
答案解析:
從題目當中得到”水仙花數“為一個3位數,則範圍确定為[100, 999]。另外需要擷取該數字的百位數字,十位數字,個位數字相加起來等于該數本身,則我們需要使用到
%
除的方式,來擷取每一個位權的數字。
代碼示例:
#include <stdio.h>
int main()
{
//a表示百位數字,b表示十位數字,c表示各位數字
int a, b, c;
for (int i = 100; i <= 999; i++)
{
a = i / 100;
b = (i / 10) % 10;
c = i % 10;
if (a * a * a + b * b * b + c * c * c == i)
{
printf("%d\n", i);
}
}
return 0;
}
運作截圖:
9.一個數如果恰好等于它的因子之和,這個數就稱為“完數”。例如,6的因子為1,2,3,而6=1+2+3,是以6是“完數”。程式設計式找出1000之内的所有完數,并按下面格式輸出其因子:
6 its factors are 1,2,3
答案解析:
因子:整數a除以整數b(b≠0) 的商正好是整數而沒有餘數,我們就說b是a的因子。整數n除以m,結果是無餘數的整數,那麼我們稱m就是n的因子。 需要注意的是,唯有被除數,除數,商皆為整數,餘數為零時,此關系才成立。因子是不包括自身的
舉一個例子:20 = 4 * 5,則4和5就是20的因子,也被稱之為因子
代碼示例:
#include<stdio.h>
int main()
{
int data, fator, sum; /* data表示要判斷的數,fator表示因子,sum表示因子之和*/
for (data = 2; data <= 1000; data++)
{
//1是所有整數的因子,是以因子之和從1開始
sum = 1;
for (fator = 2; fator <= data / 2; fator++)
{
/* 判斷data能否被fator整除,能的話fator即為因子 因子不包括自身 */
if (data % fator == 0)
{
sum += fator;
}
}
// 判斷此數是否等于因子之和 */
if (sum == data)
{
printf("%d its factors are 1, ", data);
for (fator = 2; fator <= data / 2; fator++)
{
if (data % fator == 0)
{
printf("%d, ", fator);
}
}
printf("\n");
}
}
return 0;
}
運作截圖:
10.有一個分數序列,求出這個數列的前20項之和。
2 1 \frac{2}{1} 12, 3 2 \frac{3}{2} 23, 5 3 \frac{5}{3} 35, 8 5 \frac{8}{5} 58, 13 8 \frac{13}{8} 813, 25 13 \frac{25}{13} 1325,…
答案解析:
從題目當中可以看出來,下一個分式當中的分子為上一個分式中分子和分母的和,分母為上一個分式的分子。通過這個規律不難推出下一個分式的分子和分母,需要注意的是,儲存分式的結果不能使用到整數,因為有可能會有小數的存在,是以我們需要選用浮點數
double
代碼示例:
#include <stdio.h>
//定義循環次數
#define COUNT 20
int main()
{
//定義第一個分式的分子為a, 值為2; 定義分母為b,值為1
//定義相加的和為sum,初始值為0
double a = 2, b = 1, sum = 0;
double temp;
for (int i = 0; i < COUNT; i++)
{
sum += a / b;
//記錄前一項分子
temp = a;
//前一項分子與分母之和為後一項分子
a = a + b;
//前一項分子為後一項分母
b = temp;
}
printf("前%d項之和為:sum=%9.7f\n", COUNT, sum);
return 0;
}
運作截圖:
11.一個球從100m高度自由落下,每次落地後反彈回原高度的一半,再落下,再反彈。求它在第10次落地時共經過多少米,第10次反彈多高。
答案解析:
該題目需要循環10次,在每一循環的時候,需要将下落的高度和回彈的高度加起來。需要注意的點,第10次下落不需要在計算回彈的距離了,是以需要特殊處理下。在計算每次高度的時候,會有小數存在,是以需要選用浮點數
代碼示例:
#include <stdio.h>
int main()
{
//總高度
double total_m = 100.0;
//小球經曆的米數
double total_sum = 0.0;
for (int i = 0; i < 10; i++)
{
total_sum += total_m;
total_m /= 2;
total_sum += total_m;
}
//不需要計算第10次的反彈高度,是以減去
total_sum -= total_m;
printf("小球總共經曆%lf米, 第10次反彈%lf米\n", total_sum, total_m);
return 0;
}
運作截圖:
12.猴子吃桃問題。猴子第1天摘下若幹個桃子,當即吃了一半,還不過瘾,又多吃了一個。第2天早上又将剩下的桃子吃掉一半,又多吃了一個。以後每天早上都吃了前一天剩下的一半零一個。到第10天早上想再吃時,就隻剩一個桃子了。求第1天共摘多少個桃子。
答案解析:
從題面上來看,可以推出,後一天的桃子數量 = 前一天桃子數量 / 2 - 1。是以,該公式也可以寫成前一天的桃子數量 = (後一天桃子數量+1) * 2。是以我們知道了第10天剩餘桃子的數量,則可以依次推算出桃子的前一天桃子的總數。需要注意的點,猴子隻是吃了9天,是以,我們隻需要周遊9次就可以了。
代碼示例:
#include <stdio.h>
int main()
{
int day = 9;
int prev_day_count;
int cur_day_count = 1;
while (day > 0)
{
prev_day_count = (cur_day_count + 1) * 2;
cur_day_count = prev_day_count;
day--;
}
printf("total count : %d\n", cur_day_count);
return 0;
}
運作截圖:
13.用疊代法求x= a \sqrt{a} a
。求平方根的疊代公式為
x n + 1 x_{n+1} xn+1 = 1 2 \frac{1}{2} 21( x n x_{n} xn + a x n \frac{a}{x_n} xna)
要求前後兩次求出的x的差的絕對值小于 1 0 − 5 10^{-5} 10−5。
答案解析:
題面上已經告訴兩條資訊,一個是x= a \sqrt{a} a
,是以我們可以通過a求出x的值。另外一條是 x n + 1 x_{n+1} xn+1 = 1 2 \frac{1}{2} 21( x n x_{n} xn + a x n \frac{a}{x_n} xna),可以通過x的值求出 x n + 1 x_{n+1} xn+1的值,是以,隻需要輪詢的計算,不斷的計算內插補點,直到滿足內插補點小于 1 0 − 5 10^{-5} 10−5就可以停止了
代碼示例:
#include <stdio.h>
#include <math.h>
int main()
{
float a, x0, x1;
printf("請輸入一個正數: ");
scanf("%f", &a);
x0 = a / 2;
x1 = (x0 + a / x0) / 2;
do
{
x0 = x1;
x1 = (x0 + a / x0) / 2;
} while (fabs(x0 - x1) >= 1e-5);
printf("[%f] 的平方根為 [%f]\n", a, x1);
return 0;
}
運作截圖:
14.用牛頓疊代法求下面方程在1.5附近的根:
2 x 3 x^3 x3- 4 x 2 x^2 x2 + 3 x x x - 6= 0
答案解析:
牛頓疊代法的公式為:
x n + 1 x_{n+1} xn+1 = x n x_{n} xn - f ( x n ) f ′ ( x n ) \frac{f(x_{n})}{f'(x_{n})} f′(xn)f(xn)
其中, x n x_{n} xn為輸出的值,在該題目當中為1.5。 f ( x n ) f(x_{n}) f(xn)為公式2 x 3 x^3 x3- 4 x 2 x^2 x2 + 3 x x x - 6。 f ′ ( x n ) f'(x_{n}) f′(xn)為導數,根據導數原則:
規則1: x n x^n xn = n * x ( n − 1 ) x^{(n-1)} x(n−1), 規則2:常數的導數為0。可以推導出 f ′ ( x n ) f'(x_{n}) f′(xn) = 6 x 2 x^2 x2 - 8x + 3。
在依照牛頓疊代法計算出 x n + 1 x_{n+1} xn+1的值,直到求出的內插補點小于0.00001
代碼示例:
#include <stdio.h>
#include <math.h>
int main()
{
double x1, x0, f, f1;
x1 = 1.5;
do
{
x0 = x1;
f = ((2 * x0 - 4) * x0 + 3) * x0 - 6;
f1 = (6 * x0 - 8) * x0 + 3;
x1 = x0 - f / f1;
} while (fabs(x1 - x0) >= 1e-5);
printf("方程在1.5附近的根為:%lf\n", x1);
return 0;
}
運作截圖:
15.用二分法求下面方程在(-10,10)的根:
2 x 3 x^3 x3- 4 x 2 x^2 x2 + 3 x x x - 6= 0
答案解析:
将區間劃分為兩部分,記錄區間左右端點,得到中點。每次運算将中點帶入方程進行運算,求得結果,進行分析:
結果 > 0:将中位數指派給右端點
結果 < 0:将中位數指派給左端點
以此類推…
fabs函數是一個求絕對值的函數,求出x的絕對值,和數學上的概念相同;
le-5: 1 0 − 5 10^{-5} 10−5,即0.00001
代碼示例:
#include<stdio.h>
#include<math.h>
int main()
{
double left = -10, right = 10, mid;
double temp = 10;
while (fabs(temp) > 1e-5)
{
mid = (left + right) / 2;
//((2x - 4)*x + 3) * x - 6 ==> 2x^3 - 4x^2 + 3x -6
temp = ((2 * mid - 4) * mid + 3) * mid - 6;
if (temp > 0)
{
right = mid;
}
else if (temp < 0)
{
left = mid;
}
}
printf("在(-10,10)的根為:%lf", mid);
return 0;
}
運作截圖:
16.輸出以下圖案:
*
***
*****
*******
*****
***
*
答案解析:
該題目需要關心目前行對應的從最左邊到第一顆
*
的空格數量以及星星數量。将該題分為兩個部分,前面4行和後面3行來進行拆分。
前4行中:
第一行:行号為0, 空格數為3,星星數量為1;
第二行:行号為1, 空格數為2, 星星數量為3;
第三行:行号為2, 空格數為1, 星星數量為5;
第四行:行号為3, 空格數為0,星星數量為7;
則我們可以推出兩組關系,即行号和空格數量關系為:空格數 = 3 - 行号 。行号與星星的關系為:星星數 = 2 * 行号 + 1
後三行中:
第一行:行号為0,空格數為1,星星數量為5;
第二行:行号為1, 空格數為2, 星星數量為3;
第三行:行号為2, 空格數為3,星星數量為1;
則我們推出兩組關系,即行号與數量的關系:空格數 = 行号 + 1。行号與星星的關系:星星數 = 7 - 2 * (行号+1)
基于上面的關系,我們寫出如下代碼:
代碼示例:
#include <stdio.h>
int main()
{
int cur_row, space_count, start_count;
//輸出前4行内容
for (cur_row = 0; cur_row < 4; cur_row++)
{
//計算目前行空格數量,并且進行列印
for (space_count = 3 - cur_row; space_count > 0; space_count--)
{
printf(" ");
}
//計算目前行*數量,并且進行列印
for (start_count = 2 * cur_row + 1; start_count > 0; start_count--)
{
printf("*");
}
printf("\n") ;
}
//輸出後三行
for (cur_row = 0; cur_row < 3; cur_row++)
{
for (space_count = cur_row + 1; space_count > 0; space_count--)
{
printf(" ");
}
for (start_count = 7 - 2 * (cur_row + 1); start_count > 0; start_count--)
{
printf("*");
}
printf("\n");
}
return 0;
}
運作截圖:
17.兩個乒乓球隊進行比賽,各出3人。甲隊為A,B,C 3人,乙隊為X,Y,Z 3人。已抽簽決定比賽名單。有人向隊員打聽比賽的名單,A說他不和X比,C說他不和X,Z比,請程式設計式找出3對賽手的名單。
答案解析:
從題面上得知,每隊為3人,則隐含條件為隊内三人是不能比賽的,并且A一定不會和X比,C一定不會X和Z比;則我們不難寫出判斷條件:
如果A和X比 或者 C和X比 或者 C和Z比 或者 A和B比 或者 A和C比 或者 B和C比,都是不可以的;是以我們隻要窮舉A比賽對象,B比賽對象,C比賽對象,判斷上述條件就可以了;
代碼示例:
#include <stdio.h>
int main()
{
int A_battle, B_battle, C_battle;
//如果A對戰的對象從“X”到“Z”
for (A_battle = 'X'; A_battle <= 'Z'; A_battle++)
{
//如果B對戰的對象從“X”到“Z”
for (B_battle = 'X'; B_battle <= 'Z'; B_battle++)
{
//如果C對戰的對象從“X”到“Z”
for (C_battle = 'X'; C_battle <= 'Z'; C_battle++)
{
//去除限制條件
if (A_battle == 'X' || C_battle == 'X' || C_battle == 'Z' || B_battle == A_battle || B_battle == C_battle || A_battle == C_battle)
{
continue;
}
printf("A對%c,B對%c,C對%c", A_battle, B_battle, C_battle);
}
}
}
return 0;
}
運作截圖:
c語言程式設計第五版課後答案譚浩強更多答案
c程式設計第五版課後答案譚浩強 第四章課後答案
c程式設計第五版課後答案譚浩強 第六章課後答案