面向对象笔记
第一章:C&C++表达式语句实训
第1题:剩下的苹果哪去了
考查整型数据的运算
任务描述
本关任务:程序输入苹果数 m 和人数 n,要求输出每个人平均可以分到多少个苹果,并将计算结果存入到变量 x 中。
编程要求
具体要求如下:
-
程序输入苹果总数 m 和总人数 n(数据将由平台提供,m 和 n 之间用一个空格隔开,需要你获取即可使用);
-
以“人均苹果数为:num”的格式输出,其中 num 即每个人平均分得的苹果数。
测试用例
测试输入:23 5
预期输出:人均苹果数为:4
测试输入:100 34
预期输出:人均苹果数为:2
实现代码
// 包含标准输入输出函数库 #include <stdio.h> // 定义main函数 int main() {// 定义变量,m-苹果数,n-人数,x-人均苹果数int m, n, x;// 请在Begin-End之间添加代码,计算人均苹果数/********** Begin *********/scanf("%d %d", &m, &n);x = m / n;/********** End **********/// 输出人均苹果数printf("人均苹果数为:%d",x);return 0; }
第2题:你的身材标准吗
考查浮点型数据的运算
任务描述
本关任务:输入某人的身高(cm),请你计算 Ta 要保持标准身材体重的上限和下限(单位:kg),分别存入变量 up 和 low 中。
编程要求
计算规则如下:
据说一个成年人的标准体重是其身高(单位:cm)减去100,然后再乘以 0.9所得到的公斤数。而一个人身材是否标准则是指 Ta 的真实体重是否在标准体重的加减10%
之内。
测试用例
测试输入:176
预期输出:体重范围为:61.56 -- 75.24
测试输入:160
预期输出:体重范围为:48.60 -- 59.40
实现代码
// 包含标准输入输出函数库 #include <stdio.h> // 定义main函数 int main() {float up, low;// 请在Begin-End之间添加代码,计算标准身材的体重上下限/********** Begin *********/float height, weight;scanf("%f", &height);weight = (height - 100) * 0.9;low = weight * 0.9;up = weight * 1.1;/********** End **********/// 输出标准身材的体重上下限printf("体重范围为:%.2f -- %.2f\n",low,up);return 0; }
第3题:循环加密是怎么实现的
考查字符型数据的运算
任务描述
本关任务:对 26 个大写英文字母进行循环加密,输入一个大写英文字母(明文)和一个整数秘钥,输出用秘钥对该大写英文字母加密后的结果(密文)。
编程要求
加密规则如下:
将26个大写英文字母组成一个圆环(‘A’后面是‘B’,…… ,‘Z’后面是‘A’),将明文字母往前走秘钥设定的步数就得到了密文。例如:秘钥是2时,‘A’加密后得到‘C’,‘Z’加密后得到‘B’。
测试用例
测试输入:S 5
预期输出:X
测试输入:V 15
预期输出:K
实现代码
// 包含两种I/O库,可以使用任一种输入输出方式 #include <stdio.h> #include <iostream> using namespace std; int main() {// c-存储输入的大写字母,d-存储加密后的大写字母char c, d;// step-秘钥,往前走的步数,大于等于 1,小于 26int step;// 请在Begin-End之间添加代码,计算密文存入 d 中/********** Begin *********/scanf("%c %d", &c, &step);d = c + step;if(d > 'Z' || d < 'A'){d = d - 26;}/********** End **********/// 输出密文cout << d;return 0; }
第4题:字符是怎么存储的
考查二进制数据的位运算
任务描述
本关任务:输入一个字符,输出该字符在内存中存储时对应的 0-1 串。
例如:‘A’的 ASCII 码是65,对应的8位二进制 0-1 串是 01000001。
编程要求
实现输入一个字符(该字符由平台提供,你需要获取后使用),程序输出字符对应二进制 0-1 串。
测试用例
测试输入:4
预期输出:00110100
测试输入:A
预期输出:01000001
实现代码
// 包含两种I/O库,可以使用任一种输入输出方式 #include <stdio.h> #include <iostream> using namespace std; int main() {char c; // c-存储输入的字符cin >> c; // 输入字符// 请在Begin-End之间添加代码,输出 c 的 8 位二进制表示/********** Begin *********/int num, i = 0;num = c - '0' + 48;int a[8] = {0};while(num != 0){a[i++] = num % 2;num /= 2;}for(int j = 7; j >= 0; j--){cout << a[j];}cout << endl;/********** End **********/return 0; }
第二章:C&C++控制结构实训
第1题:是闰年吗
考查分支结构
任务描述
本关任务:输入一个年份,判断该年份是否是闰年,是闰年则输出 Yes,否则输出 No。
编程要求
判断输入的年份(输入数据由平台提供,需要你获取后再使用)是否位闰年,是则输出 Yes,否则输出 No。
测试用例
测试输入:2017
预期输出:No
测试输入:2000
预期输出:Yes
实现代码
// 包含两种I/O库,可以使用任一种输入输出方式 #include <stdio.h> #include <iostream> using namespace std; int main() {int year;// 请在此添加代码,判断输入的年份是否位闰年,是则输出"Yes",否则输出"No"/********** Begin *********/cin >> year;if((year % 4 == 0 && year % 100 != 0)|| year % 400 == 0){cout << "Yes" << endl;}else{cout << "No" << endl;}/********** End **********/return 0; }
第2题:一年中的第几天
考查分支结构
任务描述
本关任务:输入一个日期,如“ 2017 6 15 ”,计算这一天是这一年的第几天(1月1日是第一天)并输出。假设输入的都是合法的日期,但别忘了考虑闰年的情况。
编程要求
通过输入的日期(数据由平台提供,以“年 月 日”的形式表示,需要你获取后使用)来判断该天是当年的第几天的要求。具体要求如下:
-
对于输入一个日期(年月日之间以一个空格间隔),形如
2017 6 15
,计算这一天是这一年的第几天并输出; -
输出形式为“年-月-日是第X天”(其中 X 是你的计算结果)。
测试用例
测试输入:2017 6 15
预期输出:2017-6-15是第166天
测试输入:2000 10 1
预期输出:2000-10-1是第275天
实现代码
// 包含两种I/O库,可以使用任一种输入输出方式 #include <stdio.h> #include <iostream> using namespace std; int main() {// y-年,m-月,d-日,n-第几天int y, m, d, n;// 请在此添加代码,计算并输出指定日期是第几天/********** Begin *********/cin >> y >> m >> d;n = 0;switch(m){case 12: n += 30;case 11: n += 31;case 10: n += 30;case 9: n += 31;case 8: n += 31;case 7: n += 30;case 6: n += 31;case 5: n += 30;case 4: n += 31;case 3:if((y % 4 == 0 && y % 100 != 0)||(y % 400 == 0) ){n += 29;}else{n += 28;}case 2: n += 31;case 1: n += d;}/********** End **********/printf("%d-%d-%d是第%d天\n",y,m,d,n);return 0; }
第3题:重排最大数
考查分支结构
任务描述
本关任务:输入一个1000(不包含1000)以内的正整数,首先将其补齐为三个数字(如果是两位数或者一位数,则前面补0),然后将这三个数字按不同顺序排列成一组数据,输出排列中最大的那个数。
编程要求
将输入的1000(不包含1000,且数据由平台提供,需要你获取后使用)以内的正整数的三个数字(如果是两位数或者一位数,则前面补0)进行重排,得到最大的数并输出。
测试用例
测试输入:5
预期输出:500
测试输入:185
预期输出:851
实现代码
// 包含两种I/O库,可以使用任一种输入输出方式 #include <stdio.h> #include <iostream> using namespace std; int main() {// n-输入的数,m-重排后的数int n, m;// 请在此添加代码,输入一个小于1000的正整数,重排出最大的数存入m中/********** Begin *********/cin >> n;int a[3] = {0};int i = 0, max, t = 0;while(n){a[i++] = n % 10;n /= 10;}for(int j = 0; j < 3; j++){for(int k = j+1; k < 3; k++){if(a[j] < a[k]){max = a[j];a[j] = a[k];a[k] = max;}}}for(i = 0; i < 3; i++){t = t * 10 + a[i];}m = t;/********** End **********/// 输出重排后的数cout << m << endl;return 0; }
第4题:黑洞陷阱
考查循环结构
任务描述
本关任务:程序输入的一个小于1000且三个数字不全相等的整数,请你输出进入黑洞的重排求差过程。本问题又称“Kaprekar问题”。
495是一个很神奇的数,被称为黑洞数或者陷阱数。
给定任何一个小于1000的正整数,经前位补0后可以得到一个三位数(两位数前面补1个0,一位数前面补2个0)。如果这个三位数的三个数字不全相等,那么经有限次“重排求差”操作(组成该数的数字重排后的最大数减去重排后的最小数),总会得到495。
编程要求
获取输入的一个小于1000且三个数字不全相等的整数(数据由平台提供,你需获取后使用),并输出进入黑洞的重排求差过程。
测试用例
测试输入:123
预期输出:
1:321-123=198
2:981-189=792
3:972-279=693
4:963-369=594
5:954-459=495
测试输入:18
预期输出:
1:810-18=792
2:972-279=693
3:963-369=594
4:954-459=495
实现代码
// 包含两种I/O库,可以使用任一种输入输出方式 #include <stdio.h> #include <iostream> using namespace std; int main() {int n;// 请在此添加代码,输出整数进入黑洞过程/********** Begin *********/int i = 1;while(scanf("%d", &n) == 1){int a, b, c, num = n,result = n;int temp;while(result != 495){a = num / 100;c = num % 10;b = num / 10 % 10;if(a < b){temp = a;a = b;b = temp;}if(b < c){temp = b;b = c;c = temp;}if(a < b){temp = a;a = b;b = temp;}int max = a * 100 + b * 10 + c, min = c * 100 + b * 10 + a;result = max - min;printf("%d:%d-%d=%d\n", i++, max, min, result);num = result;n = result;}}/********** End **********/return 0; }
第5题:是素数吗
考查循环结构
任务描述
本关任务:向程序输入一个正整数,请你判断该正整数是否是素数,如果是,则输出 Yes,否则输出 No。
编程要求
判断输入的正整数(数据由平台提供,你需要获取后使用)是否为素数,如果是,则输出 Yes,否则输出 No。
测试用例
测试输入:2
预期输出:Yes
测试输入:987
预期输出:No
实现代码
// 包含两种I/O库,可以使用任一种输入输出方式 #include <stdio.h> #include <iostream> using namespace std; int main() {int n; // 请在此添加代码,输入正整数n,如果n是素数则输出“Yes”,否则输出“No”/********** Begin *********/ cin >> n;int i;for(i = 2; i <= n / 2; i++){if(n % i == 0){break;}}if(i <= n / 2 || n <= 1){cout << "No" << endl;}else{cout << "Yes" << endl;}/********** End **********/ return 0; }
第6题:素数和
考查循环结构
任务描述
本关任务:输入 n(10≤ n ≤10000) 和 k(1≤ k ≤10),求 n 以内最大的 k 个素数,按降序排列并将和输出在最后。
编程要求
输入正整数 n 和 k(数据由平台提供,n 与 k 之间用一个空格隔开,你需要获取后使用),要求输出 n 以内最大的前 k 个素数,按降序排列并在最后输出它们的和。
测试用例
测试输入:9994 7
预期输出:9973 9967 9949 9941 9931 9929 9923 69613
测试输入:13 9
预期输出:13 11 7 5 3 2 41
实现代码
// 包含两种I/O库,可以使用任一种输入输出方式 #include <stdio.h> #include <iostream> using namespace std; int main() {int n, k;// 请在此添加代码,输入n和k,并输出n以内k个素数以及它们的和/********** Begin *********/ cin >> n >> k;int num = k, j, sum = 0;for(int i = n; i >= 2 && num > 0; i--){for(j = 2; j <= i / 2; j++){if(i % j == 0){break;}}if(j > i / 2){cout << i << " ";num--;sum += i;}}cout << sum << endl; /********** End **********/ return 0; }
# 第三章:C&C++函数实训
## 第1题:登月纸桥
### 任务描述
本关任务:编写一个函数,计算需要把纸折叠多少次(假设纸张足够大,可以无限次折叠),其厚度才能搭建一座登月纸桥,考虑到将来需要到更远的星球,所以函数需要根据具体距离计算纸张折叠的次数并返回。
### 编程要求
编写一个函数,给定一个距离和纸张的厚度(数据由平台提供,你需要获取后使用),计算需要把这张纸折叠多少次,其厚度才能搭建一座登月纸桥。考虑到将来需要到更远的星球,函数需要根据具体距离计算纸张折叠的次数并返回。
已知:月球离地球最近距离(近地点)为363300千米,最远距离(远地点)为405500千米,一张纸的厚度一般为0.088到0.114毫米。
### 测试用例
测试输入:`363300 0.088`
预期输出:`需要折叠42次`
测试输入:`405500 0.088`
预期输出:`需要折叠43次`
### 实现代码
```cpp
#include <iostream>
using namespace std;
// foldTimes-计算建纸桥的折叠次数
// 参数:dis-星际距离(千米),thick-纸的厚度(毫米)
// 返回值:建桥需要折叠的次数
int foldTimes(double dis, double thick);
int main()
{
double dis, thick;
cin >> dis >> thick;
cout << "需要折叠" << foldTimes(dis,thick) << "次" << endl;
return 0;
}
int foldTimes(double dis, double thick)
{
// 请在这里补充代码,实现函数foldTimes
/********** Begin *********/
int i;
dis *= 1000;
thick *= 0.001;
for(i = 0; dis > thick; i++){
thick *= 2;
}
return i;
/********** End **********/
}
```
## 第2题:几点几分了?
### 任务描述
本关任务:编写一个函数 whatTime,该函数通过秒表显示的秒数,计算当前的时间(几点几分几秒),计算得到的时间通过参数返回。
### 编程要求
编写函数 whatTime,该函数通过秒表显示的秒数(该数据由平台提供,你需要获取后使用),计算当前的时间(几点几分几秒),计算得到的时间通过参数返回。
### 测试用例
测试输入:`23456`
预期输出:`6:30:56`
测试输入:`34567`
预期输出:`9:36:7`
### 实现代码
```cpp
#include <iostream>
using namespace std;
void whatTime(int secs, int &h, int &m, int &s)
{
// 请在这里补充代码,设计并实现函数whatTime,使main函数中的函数调用正确
/********** Begin *********/
h = secs / 3600;
m = secs % 3600 / 60;
s = secs % 3600 % 60;
/********** End **********/
}
int main()
{
int secs; // secs秒表上的秒数
int h, m, s; // 当前时间:h-小时,m-分,s-秒
cin >> secs; // 输入秒表上的秒数
whatTime(secs,h,m,s); // 计算当前时间
cout << h << ":" << m << ":" << s << endl; // 输出当前时间
return 0;
}
```
## 第3题:这天星期几?
### 任务描述
本关任务:编写函数 whatDay,计算某年某月的1号是星期几并返回。
### 编程要求
计算输入数据年月份的1号是星期几并返回(周一到周日分别返回整数1到7)。
其中该函数的参数为输入的两个整数数据:年和月。
### 测试用例
测试输入:`2016 1`
预期输出:`2016年1月1日是星期5`
测试输入:`2017 7`
预期输出:`2017年7月1日是星期6`
### 实现代码
```cpp
#include <iostream>
using namespace std;
// 函数leapYear
int leapYear(int y)
{
if(y % 4 == 0 && y % 100 != 0 || y % 400 == 0)
return 1;
return 0;
}
// 函数whatDay:计算某年某月某日是星期几
// 参数:year-年,month-月
// 返回值:--7分别表示星期一到星期日
int whatDay(int year, int month)
{
// 请在这里补充代码,实现函数whatDay
/********** Begin *********/
int iWeek = 0;
int y = 0, c = 0, m = 0;
if ( month == 1 || month == 2 )
{
c = ( year - 1 ) / 100;
y = ( year - 1 ) % 100;
m = month + 12;
}
else
{
c = year / 100;
y = year % 100;
m = month;
}
iWeek = y + y / 4 + c / 4 - 2 * c + 26 * ( m + 1 ) / 10; //蔡勒公式
iWeek = iWeek >= 0 ? ( iWeek % 7 ) : ( iWeek % 7 + 7 ); //iWeek为负时取模
if ( iWeek == 0 ) //星期日不作为一周的第一天
{
iWeek = 7;
}
return iWeek;
/********** End **********/
}
int main()
{
int y, m, xq; // 年、月、星期几
cin >> y >> m; // 输入年月
xq = whatDay(y,m); // 计算星期几
cout << y << "年" << m << "月1日是星期"; // 输出星期
if(xq == 7)
cout << "日" << endl;
else
cout << xq << endl;
return 0;
}
```
## 第4题:打印日历
### 任务描述
本关任务:根据输入的年份和月份来输出该年月的日历。
### 编程要求
根据输入的年月(函数printMonth 的两个参数)打印该年该月的日历。日历输出格式要求如下:
1. 每个汉字(一、二、…、日)占四个字节,右对齐,由于汉字显示本身就占2个字节,所以只需要在汉字前面多输出两个空格就好了;
2. 每个日期数字占4个字节,也是右对齐,这样能使输出的日历上下对齐。
### 测试用例
![image-20210404191453729](https://gitee.com/wugenqiang/images/raw/master/02/image-20210404191453729.png)
### 实现代码
```cpp
// 包含两种I/O库,可以使用任一种输入输出方式
#include <stdio.h>
#include <iostream>
using namespace std;
// 函数printMonth:按要求的格式打印某年某月的日历
// 参数:year-年,month-月
// 返回值:无
void printMonth(int year, int month);
// leapYear:判断闰年
// 参数:y-年
// 返回值:1-是闰年,0-不是闰年
int leapYear(int y)
{
if(y % 4 == 0 && y % 100 != 0 || y % 400 == 0)
return 1;
return 0;
}
// 函数whatDay:计算某年某月的1号是星期几
// 参数:year-年,month-月
// 返回值:1到7--星期1到星期日
int whatDay(int year, int month)
{
// 1年月日是星期一
int w = 1;
int i;
// 1到year-1都是全年
for(i = 1; i < year; i++)
{
if(leapYear(i))
w += 366;
else
w += 365;
}
switch(month)
{
case 12: // 加月的
w += 30;
case 11: // 加月的
w += 31;
case 10: // 加月的
w += 30;
case 9: // 加月的
w += 31;
case 8: // 加月的
w += 31;
case 7: // 加月的
w += 30;
case 6: // 加月的
w += 31;
case 5: // 加月的
w += 30;
case 4: // 加月的
w += 31;
case 3: // 加月的
if(leapYear(year))
w += 29;
else
w += 28;
case 2: // 加月的天
w += 31;
case 1: // 1月不加了
;
}
// 得到-6,其中为星期天
w = w % 7;
// 调整星期天
if(w == 0)
w = 7;
return w;
}
// 请在下面补充代码,实现函数printMonth
/*************** Begin **************/
void printMonth(int year, int month){
int day_month;
if(month == 12 || month == 10 || month == 8 || month == 7 || month == 5 || month == 3 || month == 1)
day_month =31;
if(month == 11 || month == 9 || month == 6 || month == 4)
day_month = 30;
if(month == 2){
if(leapYear(year)){
day_month =29;
}
else day_month = 28;
}
printf(" 一 二 三 四 五 六 日\n");
int day = 1;
int order = whatDay(year, month);
for(int j=1;j<order;j++){
printf("%4s"," ");
}
for(int i = 0;i<day_month;i++){ //打印所有的日期
printf("%4d",day);
day++;
order++;
if(order==8){
printf("\n");
order=1;
}
}
printf("\n");
}
/*************** End **************/
int main()
{
// 年、月
int y, m;
// 输入年月
cin >> y >> m;
// 输出该年月的日历
printMonth(y,m);
return 0;
}
```
## 第5题:拆开了输出整数
### 任务描述
本关任务:输入一个正整数,然后把该整数的每一位数字从高位到低位顺序输出,每个数字占一行。
### 编程要求
输入一个正整数(数据由平台提供,已在主函数中获取),将该整数的每一位数字从高位到低位顺序输出,且每个数字占一行。
### 测试用例
测试输入:`132` 预期输出:
```
1
3
2
```
测试输入:`9876` 预期输出:
```
9
8
7
6
```
### 实现代码
```cpp
#include <iostream>
using namespace std;
// 递归函数splitNum:顺序输出n的各位数字,每个数字占一行
// 返回值:无
void splitNum(unsigned int n)
{
// 请在这里补充代码,实现递归函数splitNum
/********** Begin *********/
if(n / 10 == 0 ){
printf("%d\n", n % 10);
}else{
splitNum(n / 10);
printf("%d\n", n % 10);
}
/********** End **********/
}
int main()
{
unsigned n;
cin >> n; // 输入正整数n
splitNum(n); // 调用splitNum函数,顺序输出n的各位数字
return 0;
}
```
## 第6题:递归求P函数
### 任务描述
本关任务:编写函数 funP,完成数学函数*P*(*n*,*x*)函数的计算,定义如下:
![image-20210404191748236](https://gitee.com/wugenqiang/images/raw/master/02/image-20210404191748236.png)
### 编程要求
要求使用递归求数学函数 P 函数的功能。
### 测试用例
测试输入:`12 2.34`
预期输出:`P(12, 2.34)=5.1583`
测试输入:`9 9.8`
预期输出:`P(9, 9.8)=25.8949`
### 实现代码
```cpp
#include <iostream>
using namespace std;
// 函数funP:实现数学函数P函数
// 返回值:返回P(n,x)的值
double funP(int n, double x)
{
// 请在这里补充代码,实现递归函数funP
/********** Begin *********/
if (n == 0) {
return 1;
} else if (n == 1) {
return x;
} else {
return ((2 * n - 1) * funP(n - 1, x) - (n - 1) * funP(n - 2, x)) / n;
}
/********** End **********/
}
int main()
{
int n;
double x;
cin >> n >> x; // 输入n、x
cout << "P("<<n<<", "<<x<<")=" << funP(n,x) << endl;
return 0;
}
```