C++程序设计 第三章 习题
2. 计算圆的相关数据
题中给出的r、h在最后的答案中无意义
球的体积 V = 4/3 Pi r^3 球的表面积 S = 4 Pi r^2
体积公式推导和论证 : https://www.zhihu.com/question/405287938
#include <iostream>
#include <iomanip>
using namespace std;
const float PI = 3.1415926;
int main(){
float r,h;
cout << "请依次输入半径和圆柱体高度." << endl;
cin >> r >> h;
// cout << setpreise(2) << setfixed;
cout << setiosflags( ios::fixed ) << setiosflags( ios::right ) << setprecission( 2 );
cout << "\n周长:" << 2*PI*r;
cout << "\n面积:" << PI*r*r;
cout << "\n圆球表面积:" << 4 * PI * r * r;
cout << "\n球的体积:" << 4.0 / 3.0 * PI * r * r *r;
cout << "\n圆柱体体积:" << PI*r*r*h;
cout << endl;
return 0;
}
3. 转换温度单位
#include <iostream>
#include <iomanip>
using namespace std;
int main(){
float t;
cout << "请输入华氏温度:" << endl;
cin >> t;
cout << setiosflags( ios::fixed ) << setiosflags( ios::left ) << setprecision( 2 );
cout << "\n摄氏温度是:" << 5.0 / 9.0 * ( t - 32 ) ;
cout << endl;
return 0;
}
4.
(1) 要定义为char,cout输出int类型的时候会直接输出数字。
(2) 可以输出 (int) ( c1 - 0 ) 或者 (int) c1 , (int)c2
5. int 和 char 是否等价
否 最基本的 char ∈ int char1个字节、int 2-4个字节
其他等等………………
6.
7. C++ 真假
1真、0假
逻辑运算时,0是假,非0皆为真 -1也为真
(习题解析中的回答是错误的(反了))
8.
(1) a+b>c&&b==c
( (3+4) > 5 ) && ( 4 == 5 ) => false
(2) a||b+c&&b-c
a || (b+c) && (b-c) => true
(3) !(a>b) && !c||1
(!(a>b)) && (!c) || 1 => true
(4) !(x=a) && (y=b) && 0
&& 0 可直接得出false
(5) !(a+b) + c - 1 && b + c/2
(!(a+b) +c-1 ) && ( b + c/2 ) => 1 && 5 => true
9. 最大整数实现
改良:
#include <iostream>
using namespace std;
int main(){
int a,b,c, max ;
cout << "请输入3个整数:";
cin >> a >> b >> c;
max = a;
max = max>b ? max : b;
max = max>c ? max : c;
cout << "最大整数是: ";
cout << max << endl;
return 0;
}
10. 区间函数实现
其实题目并没有说 xy是整数,所以应该用float 或double
改良:
#include <iostream>
using namespace std;
int main(){
float x,y;
cout << "请输入x:";
cin >> x;
if( x< 1 ){
y = x;
}else if( x<10 ){
y = x*2 - 1;
}else{
y = x*3 - 11;
}
cout << "y是: ";
cout << y << endl;
return 0;
}
11. 转换分数
#include <iostream>
using namespace std;
int main(){
float score;
char level;
cout << "请输入成绩:";
cin >> score;
if( score >= 90 ){
level = 'A';
}else if( score >= 80 ){
level = 'B';
}else if( score >= 70 ){
level = 'C';
}else if( score >= 60 ){
level = 'D';
}else{
level = 'E';
}
cout << "成绩等级是: ";
cout << level << endl;
return 0;
}
12. 正整数分析
由于不是后面章节,不采用任何算法来做
已知位数不会超过5位
#include <iostream>
using namespace std;
int main(){
const int max = 5; // 最高位数
int n;
int l; // 总位数
int w; // 万位
int k; // 千位
int h; // 百位
int t; // 十位
int s; // 个位
cout << "请输入不大于99999的正整数:";
cin >> n;
w = n / 10000;
n -= w*10000;
l = w>0 ? 5 : 4;
k = n / 1000;
n -= k*1000;
l = k>0 ? l : 3;
h = n / 100;
n -= h*100;
l = h>0 ? l : 2;
t = n / 10;
n -= t*10;
l = t>0 ? l : 1;
s = n;
cout << "\n位数是: " << l;
cout << "\n各个位数数字是:";
int result[max] = {w,k,h,t,s};
for( int i = 0; i< max; i++ ){
if( result[i]>0 ){
cout << result[i];
if(i<max-1){ cout << ","; }
}
}
cout << "\n反向是: ";
for( int i = max-1; i >= max-l; i-- ){
cout << result[i];
}
return 0;
}
这里的各个位数变量 其实可以直接用数组中的元素来代替。 同时更进一步、将数组的容量 与 max关联,这样即成为了通用的算法。
13. 企业奖金计算 分别使用if、else
这个题目和税率计算很相似,更高区间内的要减去已经计算过的 再乘以新的比率累加
和习题解析的答案略有不同,譬如说 if规则完全想法,没有使用暂存奖金变量。
#include <iostream>
using namespace std;
int main(){
double profit; // 利润总额
double total; // 奖金总额
cout << "请输入利润总额" << endl;
cin >> profit;
// if 方式
if( profit > 1000000 ){
total += 10000 + 7500 + 10000 + 6000 + 6000; // 每个梯段都满额奖金
total += (profit - 1000000) * 0.01;
}else if( profit > 600000 ){
total += 10000 + 7500 + 10000 + 6000;
total += (profit - 600000) * 0.015;
}else if( profit > 400000 ){
total += 10000 + 7500 + 10000;
total += (profit - 600000) * 0.03;
}else if( profit > 200000 ){
total += 10000 + 7500;
total += (profit - 200000) * 0.05;
}else if( profit > 100000 ){
total += 10000;
total += (profit - 100000) * 0.075;
}else{
total += profit * 0.1;
}
cout << total << endl;
// switch 方式
// 可以看到阶梯以10万为一步比较合适
int step = (unsigned int)profit / 100000;
switch (step){
case 0: // 小于10万
total = profit * 0.1;
break;
case 1: // 10 - 20
total = 10000 + (profit-100000) * 0.075;
break;
case 2:
case 3:
total = 10000 + 7500 + (profit-200000) * 0.05;
break;
case 4:
case 5:
total = 10000 + 7500 + 10000 + (profit-400000) * 0.03;
break;
case 6:
case 7:
case 8:
case 9:
total = 10000 + 7500 + 10000 + 6000 + (profit-600000) * 0.15;
break;
default:
total = 10000 + 7500 + 10000 + 6000 + 6000 + (profit-1000000) * 0.01;
break;
}
cout << total << endl;
return 0;
}
14. 整数排序
#include <iostream>
using namespace std;
int main(){
const int max = 4;
int list[max];
int tmp;
for( int i = 0; i < max; i++ ){
cin >> list[i];
}
// 冒泡算法 向后排最大数
for( int k = 0; k<max-1; k++ ){
for( int i = k; i<max-1; i++ ){
if( list[i] > list[i+1] ){
tmp = list[i];
list[i] = list[i+1];
list[i+1] = tmp;
}
}
}
for( int i = 0; i < max; i++ ){
cout << list[i] << " ";
}
return 0;
}
15. C++最大公约数、最小公倍数
- 辗转相除法实现
#include <iostream>
using namespace std;
int GCD( int x, int y ){
return (x%y == 0) ? y : GCD(y,x%y);
}
int main(){
int a,b, gcd;
cin >> a >> b;
gcd = GCD(a,b);
cout << "\n 最大公约数: " << gcd
<< "\n 最小公倍数: " << a*b/gcd
<< endl;
return 0;
}
- 九章算术-更相减损法
仔细想一下的话,其实这本质上就是 上面的辗转相除法,因为除法本质上也就是减法,只是除法的效率更高一些
16. 字符统计
这里的字符统计,最好是合理使用 char的范围并利用 char与int转换 做大小比较。
#include <iostream>
using namespace std;
int main(){
char c;
int characters=0,digits=0,spaces=0,others=0;
while( c=getchar() != '\n' ){
if( (c >= 'A' && c <= 'Z') || (c>= 'a' && c <= 'z') ){
characters++;
}else if( c >= '0' && c <= '9' ){
digits++;
}else if( c == ' ' ){
spaces++;
}else{
others++;
}
}
cout << "\ncharacters: " << characters
<< "\ndigits: " << digits
<< "\nspaces: " << spaces
<< "\nothers: " << others
<< endl;
return 0;
}
17. 累加
这里用一个临时变量存储当前最大数,另一个存储结果。
#include <iostream>
using namespace std;
int main(){
int a,n;
long int tmp = 0;
long int result = 0;
cout << "Please enter a,n:" << endl;
cin >> a >> n;
for( int i = 0; i < n; i++ ){
tmp = tmp * 10 + a;
result = result + tmp;
}
cout << "Result is: " << result << endl;
return 0;
}
Please enter a,n: 4 5
Result is: 49380
18. 阶乘累加
同样采取 临时变量的方式节省递归造成的多于计算
#include <iostream>
using namespace std;
int main(){
int n;
long int tmp = 1;
long int result = 0;
cout << "Please enter n:" << endl;
cin >> n;
for( int i = 0; i < n; i++ ){
tmp = tmp * (i+1);
result = result + tmp;
}
cout << "Result is: " << result << endl;
return 0;
}
Please enter n: 20
Result is: 2561327494111820313
19. 水仙花数
三位数第一位必大于0,使用3层循环嵌套
很显然、解析册提供的方法,运用了较多除法,没有直接3层嵌套效率高。
#include <iostream>
using namespace std;
int main(){
for( int i = 1; i < 10; i++ ){
for ( int j = 0; j<10; j++ ){
for ( int k = 0; k<10; k++ ){
if( (i*100 + j*10 + k ) == (i*i*i) + (j*j*j) + (k*k*k) ){
cout << i << j << k << endl;
}
}
}
}
return 0;
}
153
370
371
407
完数
因子必然小于等于 sqrt(n) n/2
#include <iostream>
#include <cmath>
using namespace std;
int main(){
int sum;
int list[30] = {0};
int count = 0;
for( int n = 1; n <= 1000; n++ ){
sum = 0;
count = 0;
for( int i = 1; i <= n/2; i++ ){
if( n%i == 0 ){
sum += i;
list[count] = i;
count++;
}
}
if( sum == n ){
cout << n << ", its factors are ";
for( int k = 0; k<count; k++ ){
if(k>0){ cout << ","; }
cout << list[k];
}
cout << endl;
}
}
return 0;
}
6, its factors are 1,2,3
28, its factors are 1,2,4,7,14
496, its factors are 1,2,4,8,16,31,62,124,248
21 求分数序列之和
这题应该有两个求法,一个是普通的 分数累加 另一个是先通分,再整体计算结果, 这个方法精度应该是更高的。
“数学yyds”
#include <iostream>
using namespace std;
int main(){
// 方法1
double result;
int a,b, t;
a=2;b=1;
for( int i =0; i < 20 ){
result += (double)a/(double)b;
t = b;
b = a;
a = b + t;
}
cout << " Result is: " << result << endl;
// 方法2
int A[20]={0}; int B[20] = {0};
A[0] = 2; B[0] = 1;
for( int i =1; i < 20; i++ ){
A[i] = A[i-1] + B[i-1];
B[i] = A[i-1];
}
// 开始通分
a = 0; b = 0;
// int aMax = 0;
// int bMax = 1;
// 这里使用int 本来是可以的 不过通分的时候 分母会溢出,结果会错误
double aMax = 0;
double bMax = 1;
for( int i =0; i < 20; i++ ){
bMax *= B[i];
}
for( int i =0; i < 20; i++ ){
aMax += (bMax/B[i])*A[i];
}
result = (double)aMax/(double)bMax;
cout << " Result is: " << result << endl;
return 0;
}
Result is: 32.6603
Result is: 32.6603
从结果来看,精度“没有损失”
20 猴子吃桃问题
这个比较简单 (i +1) * 2
从第一天开始,一共吃了1..9天 第10天剩1个,所以循环9趟
#include <iostream>
using namespace std;
int main(){
int remaining = 1;
for( int i = 9; i > 0; i-- ){
remaining = (remaining + 1) * 2;
cout << "The " << i << " day : " << remaining << endl;
}
cout << "Total is: " << remaining << endl;
return 0;
}
The 9 day : 4
The 8 day : 10
The 7 day : 22
The 6 day : 46
The 5 day : 94
The 4 day : 190
The 3 day : 382
The 2 day : 766
The 1 day : 1534
Total is: 1534
25 迭代法求平方根
数学算法已给出,实现即可。 迭代法就是不不能用递归。
精度要求是 10^-5 这里我们令x0 = a
#include <iostream>
using namespace std;
int main(){
double a,sqrt, sqrt_;
cout << "Please enter the number:";
cin >> a;
sqrt_ = a*2;
sqrt = a;
while( sqrt_ - sqrt >= 0.00001 ){
sqrt_ = sqrt;
sqrt = (a/sqrt + sqrt)/2;
}
cout << "\nSqrt of " << a << " is: " << sqrt << endl;
return 0;
}
7
Please enter the number:
Sqrt of 7 is: 2.64575
24 输出图案 (半个菱形)
老实说,解题册里的方式和暴力输出。。。没啥太大区别。
1. 暴力输出
#include <iostream>
using namespace std;
int main(){
cout << "*" << endl;
cout << "* * *" << endl;
cout << "* * * * *" << endl;
cout << "* * * * * * *" << endl;
cout << "* * * * *" << endl;
cout << "* * *" << endl;
cout << "*" << endl;
return 0;
}
2. 对称循环输出
#include <iostream>
using namespace std;
void printLine( int n ){
for( int i = 0; i<n*2-1; i++ ){
if( i>0 ){ cout << " "; }
cout << "*";
}
cout << endl;
}
int main(){
int n;
cin >> n;
for( int i = 1; i<= n; i ++ ){
printLine( i>(n+1)/2 ? (n-i+1) : i );
}
return 0;
}
7
*
* * *
* * * * *
* * * * * * *
* * * * *
* * *
*
25 对战名单分析
首先列出ABC,以及已知的信息。 用!表示不比。 从逻辑推理的角度来看已经很简单了, C-Y => A=>Z => B=>X
"解题册中的答案真的不敢恭维,三层循环嵌套中嵌套几个写死的逻辑条件。"
A
- !X Y Z
B
- X Y Z
C
- !X Y !Z
接下来是看,如何用代码的形式实现这段推理。
分别用三个 3元素数组 表示对手 :
// 感觉思路是可行的,但是实现方式过于繁琐,放弃
#include <iostream>
using namespace std;
int main(){
int A[3] = {0,1,1}, int B[3] = {1}, int C[3] = {0,1,0};
bool logic = false;
while( !logic ){
// 从已知条件最多的开始
for( )
if( A[0]+A[1]+A[2] == 1 && B[0]+B[1]+B[2] == 1 && C[0]+C[1]+C[2] == 1 )
}
return 0;
}
新思路
#include <iostream>
using namespace std;
int main(){
int A[3] = {-1,0,0}, int B[3] = {0}, int C[3] = {-1,0,-1};
// 0表示未知,1表示选中,-1表示禁止
// 循环检测对手,如果只有1个人没有被禁用,则该项设为选中,同时这个人的其他项设为禁用。
bool logic = false;
return 0;
}
文章地址: C++程序设计 第三章 习题 - Sprite keep learning
最近回复