C++习题(二)
题目综述
-
输入三个实数,按从大到小的顺序输出 。
-
采用海伦公式,求三角形的面积 ,三角形的三个边从键盘输入 。
-
打印出所有的“水仙花数”,所谓“水仙花数”是指一个三位数,其各位数字的立方和等于该数本身。 如 153 是一水仙花数,因为 153 = 13 + 53 + 33。
-
从键盘输入一个数 N 计算 1 + 2 + 3 + …… + N 的值。 要求: 能一直输入一直计算,直到输入一个负数停止 。
-
输出以下 4*5 的矩阵。
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20 -
从键盘随机输入 10 个数,统计其中正数的个数及正数的平均数
-
已知半径 radius,采用循环结构计算半径 1~10 区间内圆的面积 area 。且当 area > 100 时结束程序运行。
-
从键盘输入一个数 m ,判断这个数是否为素数。
-
求 100 - 200 之间的全部素数并按照每 5 个一行进行输出
-
从键盘输入一个正整数 n ,输出一个星型图案,其中第 n 行的 * 号个数为 2n - 1 个。如 n = 4,输出的图形为:
题目详解
1.输入三个实数,按从大到小的顺序输出 。
思路: 三个数的比较,可以理解成先比较两个数,然后看看第三个数可以放在哪个位置
通过对三个数中两个数排序,再插入第三数的方法进行比较输出
- 先对前两个数排序
if (a > b)//对a ,b排序
{ //如果a比b大,则将a,b调换
double ntemp = 0;
ntemp = a;
a = b;
b = ntemp;
}
-
排序之后确定 a 比 b 小,这时插入第三个数 c ,此时 c 有且仅存在三种位置:
① 在 a 前面,这时 c < a < b
② 在 a ,b 之间,这时 a < c < b
③ 在 b 后面,这时 a < b < c
所以先看 a ,c 之间的关系,如果 a < c ,然后看 b ,c 之间关系,比较后输出
如果 c < a ,直接输出 c < b < a
if (a < c) //将 c 分别与 a ,b 比较
{
// a < c
if (c <= b)
{ //此时 a < c <= b
cout << "这3个数从大到小的顺序为: " << b << " "
<< c << " "
<< a << " " << endl;
}
else
{ //此时 a < b < c
cout << "这3个数从大到小的顺序为: " << c << " "
<< b << " "
<< a << " " << endl;
}
}
else // c < a
{ //此时 c < a < b
cout << "这3个数从大到小的顺序为: " << b << " "
<< a << " "
<< c << " " << endl;
}
【完整代码】
// 1、输入三个实数,按从大到小的顺序输出。
#include <iostream>
using namespace std;
int main()
{
//初始化变量
double a, b, c;
cout << "请输入任意3个数,中间用空格隔开:" << endl;
cin >> a >> b >> c; //输入 3 个数
if (a > b)//对a和b排位置
{
//如果 a 比 b 大,则将 a ,b 调换
double ntemp = 0;
ntemp = a;
a = b;
b = ntemp;
}
if (a < c) //将 c 分别与 a ,b 比较
{
// a < c
if (c <= b)
{ //此时 a < c <= b
cout << "这3个数从大到小的顺序为: " << b << " "
<< c << " "
<< a << " " << endl;
}
else
{ //此时 a < b < c
cout << "这3个数从大到小的顺序为: " << c << " "
<< b << " "
<< a << " " << endl;
}
}
else // c < a
{ //此时 c < a < b
cout << "这3个数从大到小的顺序为: " << b << " "
<< a << " "
<< c << " " << endl;
}
return 0;
}
【运行结果】
2.采用海伦公式,求三角形的面积 ,三角形的三个边从键盘输入 。
-
海伦公式:(假设三角形三条边的边长分别为a,b,c)
p = (a + b + c) / 2
S = (p * (p - a) * (p - b) * (p - c))1/2
double p = (a + b + c) / 2.0; // p 是周长的一半
double S = sqrt(p * (p - a) * (p - b) * (p - c)); //海伦公式
【完整代码】
//2、采用海伦公式,求三角形的面积,三角形的三个边从键盘输入。
#include <iostream>
#include<cmath>
using namespace std;
int main()
{
//初始化变量
double a, b, c;
cout << "请输入三角形任意3条边的边长,中间用空格隔开:" ;
cin >> a >> b >> c; //输入 3 个数
double p = (a + b + c) / 2.0; // p 是周长的一半
double S = sqrt(p * (p - a) * (p - b) * (p - c)); //海伦公式
cout << "该三角形的面积为:" << S << endl;
return 0;
}
【运行结果】
3. 打印出所有的“水仙花数”,所谓“水仙花数”是指一个三位数,其各位数字的立方和等于该数本身。 如 153是一水仙花数,因为 153 = 13 + 53 + 33。
思路:
①遍历所有三位数
②把当前的三位数拆成百位、十位和个位
③做判定,如果符合就输出
拆分三位数的方法: 对于三位数 i
i / 100 → 能取出 i 的百位数 a
(i - 100 * a) / 10 → i - 100 * a 除去了百位数,然后除10得到十位数 b
i - 100 * a - 10 * b → 除去百位数和十位数之后得到个位数 c
//取百位、十位、个位数
a = i / 100;
b = (i - 100 * a) / 10;
c = (i - 100 * a - 10 * b);
判定方法 → pow( x , 3 ) 表示 x3
if (i == pow(a,3) + pow(b, 3) + pow(c, 3)) // i = a^3 + b^3 + c^3
【完整代码】
/*3、打印出所有的“水仙花数”,所谓“水仙花数”是指一个三位数,其各位数字的立方和等于该数本身。
如 153 是一水仙花数,因为 153 = 1^3 + 5^3 + 3^3。
注:若给定一个数 num ,通过算术表达式表示出百位、十位、个位,然后通过分支结构和循环结构实现。
*/
#include <iostream>
#include<cmath>
using namespace std;
int main()
{
//初始化变量
int a, b, c;
cout << "水仙花数总共有:" << endl;
for (int i = 100; i < 1000; ++i)
{
//取百位、十位、个位数
a = i / 100;
b = (i - 100 * a) / 10;
c = (i - 100 * a - 10 * b);
//判定
if (i == pow(a,3) + pow(b, 3) + pow(c, 3))
{
// i = a^3 + b^3 + c^3
cout << i << " ";
}
}
cout << endl;
return 0;
}
【运行结果】
4. 从键盘输入一个数 N 计算 1 + 2 + 3 + …… + N 的值。 要求: 能一直输入一直计算,直到输入一个负数停止 。
思路:关键是" 能一直输入一直计算 ",所以先用一个不会停的 while 循环,然后在循环内输入数据 N ,判定如果 N 是负数就用 break 跳出循环,如果 N 不是负数就正常的求和输出 Sum ,且在输出 Sum 之后要把 Sum 清零。
【关于能 " 一直输入一直计算 " 】
while (1)
{ /*
这个循环除非有 break 不然不会停下来
此时就可以设计 N 的输入和对 N 的判定
如果 N 是正的就求和
如果 N 是其它类型就直接 break 跳出循环
*/
//在循环内部输入数据
cout << "请输入正整数 N=";
cin >> N;
if (N > 0)
{
//********求和部分*********
//输出之后 Sum 要清零
Sum = 0;
}
else
//此时 N 是负数,按照题意跳出循环
{
cout << "输入的N不合法,程序结束" << endl;
break;
}
}
【完整代码】
/*4、 从键盘输入一个数 N 计算 1 + 2 + 3 + …… + N 的值 要求能一直输入一直计算,直到输入一个负数停止*/
#include <iostream>
#include<cmath>
using namespace std;
int main()
{
//初始化变量
int N(1),Sum(0);
while (1)
{
//在循环内部输入数据
cout << "请输入正整数 N=";
cin >> N;
if (N > 0)
{
for (int i = 1; i <= N; ++i)
{
Sum += i;
}
if (N == 1 || N == 2)
{
cout << "S = " << Sum << endl;
}
else
{
cout << "S = 1 + …… + " << N << " = " << Sum << endl;
}
//输出之后 Sum 要清零
Sum = 0;
}
else
//此时 N 是负数,按照题意跳出循环
{
cout << "输入的N不合法,程序结束" << endl;
break;
}
}
cout << endl;
return 0;
}
【运行结果】
5. 输出以下 4*5 的矩阵。
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
注:可以用循环的嵌套来处理此问题。用外循环来输出一行数据,用内循环来输出一列数据,按矩阵的格式(每行5个数据)输出。
思路:观察到矩阵中每一个元素值都是行数乘列数
/*5、 输出以下 4 * 5 的矩阵。
1 2 3 4 5
2 4 6 8 10
3 6 9 12 15
4 8 12 16 20
注:可以用循环的嵌套来处理此问题。
用外循环来输出一行数据,用内循环来输出一列数据,按矩阵的格式(每行5个数据)输出。
*/
#include <iostream>
using namespace std;
int main()
{
//外循环 i 表示此时遍历的行数
for (int i = 1; i <= 4; ++i)
{
//内循环 j 表示此时遍历的列数
for (int j = 1; j <= 5; ++j)
{
// i * j 刚好是矩阵上每个元素的数值大小
cout << i * j << "\t";
}
//输出完 5 列之后换行
cout << endl;
}
return 0;
}
【运行结果】
6. 从键盘随机输入 10 个数,统计其中正数的个数及正数的平均数
注:可以考虑采用分支结构、循环结构和continue语句实现。
思路:准备一个数组来装这十个数,遍历数组元素,准备计数器 count 来统计数组内正数的个数,并对这些正数求和得到 Sum ,再求平均数 average
//6、从键盘随机输入 10 个数,统计其中正数的个数及其平均数
//注:可以考虑采用分支结构、循环结构和 continue 语句实现。
#include <iostream>
using namespace std;
int main()
{
double a[10]; //创建 10 个数的数组
cout << "请输入任意 10 个数:" << endl;
for (int i = 0; i < 10;++i)
{
cin >> a[i];
}
int count = 0;
double sum = 0.0, average = 0.0;
//对数组内数据进行统计
for (int i = 0; i < 10; ++i)
{
//找到大于 0 的元素
if (a[i] > 0)
{
++count;
sum += a[i];
}
average = sum / count;
}
cout << "这 10 个数里的正数个数为:" << count << "个\n" << "这些正数的平均数为:" << average << endl;
return 0;
}
【运行结果】
7. 已知半径 radius,采用循环结构计算半径 1~10 区间内圆的面积 area 。且当 area > 100 时结束程序运行。
思路:设定一个不停的 while 循环,在循环内输入半径 radius 之后,先判定半径是否在 1~10 区间内,如果不是就 continue 重新输入半径,如果半径合法就计算圆面积 area ,然后再判定该面积是否超过 100 ,如果超过 100 就用 break 跳出循环,如果没超过就继续输入半径算面积
/*7、已知半径 radius 采用循环结构计算半径 1 ~ 10 区间内圆的面积 area。
且当 area > 100 时结束程序运行。
注:可以考虑采用循环结构和break语句实现。
*/
#include <iostream>
using namespace std;
//定义数据 PI
#define PI 3.14159
int main()
{
double radius;
double area = 0.0;
while (1)
{
//输入半径
cout << "请输入半径值:";
cin >> radius;
//确保半径在 1 ~ 10 之间再计算面积
if (radius >= 1 && radius <= 10)
{
//要先算面积,然后再判定面积是否过大
area = PI * radius * radius;
cout << "半径为" << radius << "的圆面积为" << area;
//面积大于 100,程序结束,用 break
if (area > 100)
{
cout << endl;
cout << "圆面积超过 100 ,程序结束!" << endl;
break;
}
}
//再讨论半径不在 1 ~ 10 之间的情况
else
{
cout << "半径值不在 1 ~ 10 之间!" << endl;
}
//换两行
cout << endl;
cout << endl;
}
return 0;
}
【运行结果】
8. 从键盘输入一个数 m ,判断这个数是否为素数。
思路:素数的判定是除了 1 和它自己本身以外不能被其它数整除
①可以先从 2 开始遍历,一直遍历到根号 m ,看看这个遍历出来的数 i 是不是 m 的倍数,如果是,m 就一定不是素数,可以直接 break 跳出循环
for(int i = 2;i < number;++i)
{ //如果此时 i 是 number 的倍数,循环就可以直接停了
if (number % i == 0)
{ cout << number << " 不是素数!" << endl;
break;
}
}
②同时准备一个判定用的数 judge 并初始化为 0 ,如果出现 i 是 m 的倍数,judge 可以变化(如+1), 如果循环结束之后 judge 值还是 0 ,就说明前面遍历的所有 i 都不是 m 的倍数,那么这个 m 就是素数
int judge = 0; //judge 用于评判遍历完成之后是否存在 i 是 number 的倍数
for(int i = 2;i < number;++i)
{
//如果此时 i 是 number 的倍数,循环就可以直接停了
if (number % i == 0)
{
cout << number << " 不是素数!" << endl;
++judge; //如果有这样的 i ,judge 发生变化
break;
}
}
//在遍历完成之后,如果 judge 不变,就说明前面没有 i 是 number 的倍数
//这样的 number 就肯定是素数
if (judge == 0) { cout << number << " 是素数!" << endl; }
【完整代码】
/*8、从键盘输入一个数 m ,判断这个数是否为素数。
注:可以考虑采用分支结构和循环结构实现。在 C++自带的 cmath类库中包含有 sqrt() 函数
可以实现对一个数的开方。
例如:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
double value = 9.0;
cout << sqrt(value) << endl;
return 0;
}
*/
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
int number = 0;
cout << "请输入一个整数 m = ";
cin >> number;
//素数:除了 1 和它本身以外,没有其它数是这个数的倍数
//取 number 开方,只用看前一半的数
int num = sqrt(number);
int judge = 0; //judge 用于评判遍历完成之后是否存在 i 是 number 的倍数
for(int i = 2;i < number;++i)
{
//如果此时 i 是 number 的倍数,循环就可以直接停了
if (number % i == 0)
{
cout << number << " 不是素数!" << endl;
++judge; //如果有这样的 i ,judge 发生变化
break;
}
}
//在遍历完成之后,如果 judge 不变,就说明前面没有 i 是 number 的倍数
//这样的 number 就肯定是素数
if (judge == 0) { cout << number << " 是素数!" << endl; }
return 0;
}
【运行结果】
9. 求 100 - 200 之间的全部素数并按照每 5 个一行进行输出
思路:判定素数的方法同上,注意 “ 每5个一行进行输出 ” ,需要设一个计数器 count ,每次找到一个素数并且输出之后 count + 1 ,然后在外循环中判定 count 是否满 5 ,如果满了就手动换行并将计数器清零
尝试另一种确定遍历中所有 j 都不是 i 倍数的方法:
//当i不能被此时的j除尽时,说明此时的j不是i的倍数
if ((i % (j)) != 0)
{
//如果这样的 j (不是 i 的倍数的 j )又恰好是 i 前面那个数
//说明此时 j 前面所有的数都不是i的倍数
//那么这个时候 i 就肯定是素数了
if (j == (i - 1))
{
//然后根据题目的要求, 5 个数输出一次
//可以做一个计数器,每一次输出一个 i ,计数器 + 1
//这样就知道输出这个 i 之后要不要换行了
cout << i << " ";
//输出完 i 之后,计数器 + 1
++count;
}
continue;
}
【完整代码】
/*9、求 100 - 200 之间的全部素数并按照每 5 个一行进行输出*/
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
cout << " 100 - 200 以内的素数有:" << endl;
//初始化变量,计数器(用于统计输出每一行输出素数的个数)
int number = 200,count = 0;
//第一次循环遍历,每次选出一个数 i ,判断数 i 是否是素数
for (int i = 100; i < number + 1; i++)
{
//现在判断数 i 是否为素数
//判断一个数 i 是否为素数,就从 2 开始遍历 j ,看看 i 能不能被j除尽
for (int j = 2; j < i; ++j)
{
//当 i 不能被此时的j除尽时,说明此时的 j 不是 i 的倍数
if ((i % (j)) != 0)
{
//如果这样的 j (不是 i 的倍数的 j )又恰好是 i 前面那个数
//说明此时 j 前面所有的数都不是i的倍数
//那么这个时候 i 就肯定是素数了
if (j == (i - 1))
{
//然后根据题目的要求, 5 个数输出一次
//可以做一个计数器,每一次输出一个 i ,计数器 + 1
//这样就知道输出这个 i 之后要不要换行了
cout << i << " ";
//输出完 i 之后,计数器 + 1
++count;
}
continue;
}
else
{
break;
}
}
//上面for循环完全走一次之后,就可以判断当下的 i 是否为素数,是否需要输出
//此时注意计数器的情况
//如果计数器满 5 ,就说明之前已经在这一行里前面已经输出了 5 个数
//需要手动换行,并将计数器清零
if (count == 5)
{
//手动换行
cout << endl;
//计数器清零
count = 0;
}
}
//最后换个行
cout << endl;
system("pause");
return 0;
}
【运行结果】
10. 从键盘输入一个正整数 n ,输出一个星型图案,其中第 n 行的 * 号个数为 2n - 1 个。如 n = 4,输出的图形为:
【找规律】
<当 n = 4 时>
上半部分输出情况:
第1行输出了 3个空格(4 - 1 = 3)、1个 * 号(2 * 1 - 1 = 1)
第2行输出了 2个空格(4 - 2 = 2)、3个 * 号(2 * 2 - 1 = 3)
第3行输出了 1个空格(4 - 3 = 1)、5个 * 号(2 * 3 - 1 = 5)
第4行输出了 0个空格(4 - 4 = 0)、7个 * 号(2 * 4 - 1 = 7)
下半部分输出情况:
第1行输出了 1个空格、5个 * 号
第2行输出了 2个空格、3个 * 号
第3行输出了 3个空格、1个 * 号
思路:
- 上图 n = 4 时总共有 7 行 —→ 推出 输入 n 之后图案一共有 2n - 1 行
- 整个星型图案是由 * 和 " " 组成,没有输出 * 号的地方可以理解为输出了空格
- 上半部分可以看作:第 i 行依次输出 n - i 个空格、 2n - 1 个 * 号
- 下半部分可以看作:第 i 行依次输出 i 个空格、" * "号数则先统计好前面空格输出数,再用 2n - 1 的值减去空格输出数和当前行数 i
【上半部分图案代码】
//1.上半部分图案
//用 i 模拟行数,上半部分共有 n 行
for(int i = 1; i <= n; ++i)
{
//输出空格
//其中每一行总共有 n - i 个空格,用循环输出
for (int j = 0; j < n - i; ++j)
{
cout << " ";
}
//输出 * 号
//按照题意,每一行共输出 2n - 1 个 * 号,用循环输出
for (int m = 0; m < 2 * i - 1 ; ++m) { cout << "*"; }
//每次输出完一行之后手动换行
cout << endl;
}
【下半部分图案代码】
//2.下半部分图案
//还是用 i 来模拟行数,但下半部分总共只有 n - 1 行
for (int i = 1; i < n; ++i)
{
//设定计数器,用来统计第 i 行总共输出了多少个空格
int count = 0;
//输出空格
//每行空格数与当前行数一样,所以 i 行输出 i 个空格
for (int j = 0; j < i; ++j)
{
//同时记录空格数
//因为 j 在循环之后就不存在了,所以得用一个作用域更大一些的变量来存空格数
++count;
cout << " ";
}
//输出 * 号
// * 号个数 = 图案总行数( 2n - 1 ) - 当前行数( i ) - 已经输出的空格数( count )
for (int m = 0; m < ((2 * n - 1) - i - count); ++m){ cout << "*"; }
//最后手动换个行
cout << endl;
}
【完整代码】
/*10、从键盘输入一个正整数 n ,输出一个星型图案,其中第n行的*号个数为 2n - 1 个。
如 n = 4 ,2n - 1 = 7 输出的图形为:
*
***
*****
*******
*****
***
*
注:首先推算出这个星型图形上半部分和下半部分的递推表达式,其次考虑采用循环结构实现。
*/
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
//初始化变量
int n = 0;
cout << "请输入正整数n:";
cin >> n;
//遍历循环,观察到星型图案共有2n-1行,要分成上下两部分处理
/*
整个星型图案是由 " * " 和 " " 组成,没有输出 * 号的地方可以理解为输出了空格
很显然,第n行也就是*号最多的一行全部都输出了 * 号,总共输出了 2n - 1 个
那么可以这样理解:图案中每一行都输出了 2n - 1 个符号
<当 n = 4 时>
上半部分输出情况:
第1行输出了 3个空格(4 - 1 = 3)、1个 * 号(2 * 1 - 1 = 1)
第2行输出了 2个空格(4 - 2 = 2)、3个 * 号(2 * 2 - 1 = 3)
第3行输出了 1个空格(4 - 3 = 1)、5个 * 号(2 * 3 - 1 = 5)
第4行输出了 0个空格(4 - 4 = 0)、7个 * 号(2 * 4 - 1 = 7)
所以上半部分可以看作:第i行依次输出 n - i 个空格、 2n - 1 个 * 号
下半部分输出情况:
第1行输出了 1个空格、5个 * 号
第2行输出了 2个空格、3个 * 号
第3行输出了 3个空格、1个 * 号
每一行的" * "号可以这样算:先统计好前面空格输出数,再用 2n - 1 的值减去空格输出数和当前行数
*/
//1.上半部分图案
//用 i 模拟行数,上半部分共有 n 行
for(int i = 1; i <= n; ++i)
{
//输出空格
//其中每一行总共有 n - i 个空格,用循环输出
for (int j = 0; j < n - i; ++j)
{
cout << " ";
}
//输出 * 号
//按照题意,每一行共输出 2n - 1 个 * 号,用循环输出
for (int m = 0; m < 2 * i - 1 ; ++m) { cout << "*"; }
cout << endl;
}
//2.下半部分图案
//还是用 i 来模拟行数,但下半部分总共只有 n - 1 行
for (int i = 1; i < n; ++i)
{
//设定计数器,用来统计第i行总共输出了多少个空格
int count = 0;
//输出空格
//每行空格数与当前行数一样,所以 i 行输出 i 个空格
for (int j = 0; j < i; ++j)
{
//同时记录空格数
//因为 j 在循环之后就不存在了,所以得用一个作用域更大一些的变量来存空格数
++count;
cout << " ";
}
//输出 * 号
// * 号个数 = 图案总行数( 2n - 1 ) - 当前行数( i ) - 已经输出的空格数( count )
for (int m = 0; m < ((2 * n - 1) - i - count); ++m){ cout << "*"; }
//最后换个行
cout << endl;
}
cout << endl;
system("pause");
return 0;
}
【运行结果】