A.圆和圆柱体计算(继承)

题目描述

定义一个CPoint点类,包含数据成员x,y(坐标点)。

以CPoint为基类,派生出一个圆形类CCircle,增加数据成员r(半径)和一个计算圆面积的成员函数。
再以CCircle做为直接基类,派生出一个圆柱体类CCylinder,增加数据成员h(高)和一个计算体积的成员函数。
生成圆和圆柱体对象,调用成员函数计算面积或体积并输出结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;

class CPoint
{
protected:
double x, y;
public:
CPoint(double x1, double y1):x(x1),y(y1){}

};

class CCircle :public CPoint
{
protected:
double r;
public:
CCircle(double x1,double y1,double r1):CPoint(x1,y1),r(r1){ }
double Area()
{
return 3.14 * pow(r, 2);
}
void print()
{
cout << "Circle:(" << x << "," << y << ")," << r << endl;
cout << "Area:" << Area() << endl;
}
};

class CCylinder :public CCircle
{
protected:
double h;
public:
CCylinder(double x1,double y1,double r1,double h1):CCircle(x1,y1,r1),h(h1){}
double Volume()
{
return 3.14 * pow(r, 2) * h;
}
void print()
{
cout << "Cylinder:(" << x << "," << y << ")," << r << "," << h << endl;
cout << "Volume:" << Volume() << endl;
}
};

int main()
{
double x, y, r, h;
cin >> x >> y >> r;
CCircle a(x, y, r);
a.print();
cin >> x >> y >> r >> h;
CCylinder b(x, y, r, h);
b.print();

return 0;
}

B.三维空间的点(继承)

题目描述

定义一个平面上的点C2D类,它含有一个getDistance()的成员函数,计算该点到原点的距离;从C2D类派生出三维空间的点C3D类,它的getDistance()成员函数计算该点到原点的距离。试分别生成一个C2D和C3D的对象,计算它们到原点的距离。

三维空间的两点(x, y, z)和(x1, y1, z1)的距离公式如下:

[(x-x1)^2+(y-y1)^2+(z-z1)^2]^(1/2)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include<iostream>
#include<iomanip>
#include<cmath>
using namespace std;

class C2D
{
protected:
int x;
int y;
public:
C2D(int x1, int y1):x(x1),y(y1){}
C2D(){}
void setXY(int x1, int y1)
{
x = x1;
y = y1;
}
double getDistance()
{
return sqrt(pow(x, 2) + pow(y, 2));
}
};

class C3D :public C2D
{
protected:
int z;
public:
void setZ(int z1)
{
z = z1;
}
double getDistance()
{
return sqrt(pow(x, 2) + pow(y, 2) + pow(z, 2));
}
};

int main()
{
int x;
int y;
int z;
cin >> x >> y;
C2D a1(x, y);
cout << a1.getDistance() << endl;
cin >> x >> y >> z;
C3D b1;
b1.setXY(x, y);
b1.setZ(z);
cout << b1.getDistance() << endl;
cin >> x >> y >> z;
C3D b2;
b2.setXY(x, y);
b2.setZ(z);
cout << b2.getDistance() << endl;
C2D a2(x, y);
cout << a2.getDistance() << endl;

return 0;
}

C.时钟模拟(继承)

题目描述

定义计数器类,包含保护数据成员value,公有函数increment计数加1。
定义循环计算器继承计数器类,增加私有数据成员:最小值minValue,maxValue,
重写公有函数increment,使得value在minValue~maxValue区间内循环+1。
定义时钟类,数据成员是私有循环计数器对象小时hour、分钟minute、秒second,公有函数time(int s)计算当前时间经过s秒之后的时间,即hour,minute,second的新value值。
定义时钟类对象,输入当前时间和经过的秒数,调用time函数计算新时间。
根据题目要求,增加必要的构造函数、析构函数和其他所需函数。
因为clock和time是系统内置函数,为了避免重名,请不要使用clock或者time作为类名或者函数名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include<iostream>
using namespace std;

class Chronograph
{
protected:
int value;
public:
Chronograph(int v):value(v){}
void increment()
{
value++;
}
int getV()
{
return value;
}
};

class Calculators :public Chronograph
{
private:
int minValue;
int maxValue;
public:
Calculators(int min_v, int max_v, int v) :minValue(min_v),maxValue(max_v), Chronograph(v) {}
void increment()
{
value = (value - minValue + 1) % (maxValue - minValue + 1) + minValue;
}

};

class CClock
{
private:
Calculators hour;
Calculators minute;
Calculators second;
public:
CClock(int h,int m,int s):hour(0,23,h),minute(0,59,m),second(0,59,s){}
void ttime(int s)
{
while (s--)
{
second.increment();
if (second.getV() == 0)
{
minute.increment();
if (minute.getV() == 0)
{
hour.increment();
}
}
}
}
void display()
{
cout << hour.getV() << ":" << minute.getV() << ":" << second.getV() << endl;
}
};

int main()
{
int n;
int h, m, s;
int passtime;
cin >> n;
while (n--)
{
cin >> h >> m >> s>>passtime;
CClock c(h, m, s);
c.ttime(passtime);
c.display();
}

return 0;
}

D.学生成绩计算(继承)

题目描述

定义Person类具有姓名、年龄等属性,具有输出基本信息的display函数。
选修《面向对象程序设计》课程的学生在Person类的基础上,派生出子类:免听生和非免听生。子类继承父类成员,新增其他成员、改写display函数。
非免听生具有平时成绩、考试成绩和总评成绩三个属性,总评成绩根据(平时成绩*40%+考试成绩*60%)计算的结果,85分(包含)以上为A,75分(包含)-85分(不包含)为B,65分(包含)-75分(不包含)为C,60分(包含)-65分(不包含)为D,60分(不包含)以下为F。
免听生只有考试成绩和总评成绩两个属性,总评成绩100%根据考试成绩对应上述等级制成绩。
定义上述类并编写主函数,输入类型符号,若输入R,根据学生基本信息、平时成绩和考试成绩,建立非免听生对象,若输入S,根据学生基本信息、考试成绩,建立免听生对象。计算学生的总评成绩,并输出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include<iostream>
#include<cstring>
using namespace std;

class Person
{
protected:
string name;
int age;
double final;
public:
Person() {};
Person(string n, int a) :name(n), age(a) {};
char rating()
{
if (final >= 85)
{
return 'A';
}
else if (final >= 75)
{
return 'B';
}
else if (final >= 65)
{
return 'C';
}
else if (final >= 60)
{
return 'D';
}
else if (final < 60)
{
return 'F';
}
}
void display()
{
cout << name << " " << age << endl;
}
};

class Freelisten :public Person
{
protected:
double grade;
public:
Freelisten() {};
Freelisten(string n, int a, int g) :Person(n, a), grade(g) {};
void display()
{
final = grade;
cout << name << " " << age << " " << rating() << endl;
}
};

class Nolisten :public Person
{
protected:
double grade, usual;
public:
Nolisten() {};
Nolisten(string n, int a, int u, int g) :Person(n, a), usual(u), grade(g) {};
void display()
{
final = 0.4 * usual + 0.6 * grade;
cout << name << " " << age << " " << rating() << endl;
}
};

int main()
{
int t, usual, test, age;
string name;
char type;
cin >> t;
while (t--)
{
cin >> type;
if (type == 'R')
{
cin >> name >> age >> usual >> test;
Nolisten a(name, age, usual, test);
a.display();
}
else if (type == 'S')
{
cin >> name >> age >> test;
Freelisten b(name, age, test);
b.display();
}
}
return 0;
}

E.新旧身份证(继承)

题目描述

按下述方式定义一个日期类CDate和描述15位身份证号的旧身份证类COldId:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class CDate 
{
private:
int year, month, day;
public: CDate(int, int, int); bool check(); //检验日期是否合法
bool isLeap(); void print();
};
class COldId
{
protected:
char* pId15, * pName; //15位身份证号码,姓名
CDate birthday; //出生日期
public:
COldId(char* pIdVal, char* pNameVal, CDate& day);
bool check(); //验证15位身份证是否合法
void print();
~COldId();
};

然后以COldId为基类派生18位身份证号的新身份证类CNewId,并增加3个数据成员:pId18(18位号码)、issueDay(签发日期)和validYear(有效期,年数),并重新定义check()和print()。

15位身份证号扩展为18位身份证号的规则为:前6位号码保持一致,年份由2位变为4位(在前面加上19,例如88变为1988),剩余号码都保持一致,再加上第18位校验码。

身份证第18位校验码的生成方法:
1、将身份证号码前17位数分别乘以7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2。然后将其相加。
2、将17位数字与系数乘加的和除以11,得到余数。
3、余数与校验码的对应关系为1,0,X,9,8,7,6,5,4,3,2。也即:如果余数是3,身份证第18位就是9。如果余数是2,身份证的最后一位号码就是X。

主函数定义一个派生类对象,并用派生类对象调用check(),若返回false则输出“illegal id”否则调用print()输出身份证信息。check()对身份证合法性进行验证的规则:

  1. 确认18位号码是从15位号码扩展的,且第18位校验码正确.
  2. 身份证中的出生日期合法.
  3. 身份证号码中不含非法字符.
  4. 身份证号码的长度正确.
  5. 身份证目前处于有效期内,假设当前日期为2021年11月9日。
  6. 签发日期合法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstring>
using namespace std;

class CDate
{
private:
int year, month, day;

public:
CDate(int y, int m, int d) : year(y), month(m), day(d) {}
int getYear() { return year; }
int getMonth() { return month; }
int getDay() { return day; }
bool check()
{
int monthDay[] = {
31, isLeap() ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
if (day < 0 || year < 0 || month < 0 || year > 2015 || month > 12 || day > monthDay[month - 1])
return 0;
else
return 1;
}
bool isLeap()
{
return (year % 4 == 0 && year % 100 != 0 || year % 400 == 0);
}
void print()
{
cout << year << "年" << month << "月" << day << "日";
}
};

class COldID
{
protected:
char* p_id15, * p_name;
CDate birthday;
public:
COldID(char* p_idval, char* p_nameval, int y, int m, int d) : birthday(y, m, d)
{
p_id15 = new char[strlen(p_idval) + 1];
strcpy(p_id15, p_idval);
p_name = new char[strlen(p_nameval) + 1];
strcpy(p_name, p_nameval);
}
int check()
{
if (!birthday.check())
return 0;
if ((*(p_id15 + 6) - '0') * 10 + (*(p_id15 + 7) - '0') != birthday.getYear() % 100 ||
(*(p_id15 + 8) - '0') * 10 + (*(p_id15 + 9) - '0') != birthday.getMonth() ||
(*(p_id15 + 10) - '0') * 10 + (*(p_id15 + 11) - '0') != birthday.getDay())
return 0;
for (int i = 0; i < 15; i++)
{
if ('0' > *(p_id15 + i) || *(p_id15 + i) > '9')
return 0;
}
if (strlen(p_id15) != 15)
return 0;
return 1;
}
void print()
{
cout << p_name << endl;
}
~COldID() {}
};
class CNewID : public COldID
{
char* p_id18;
CDate issueday;
int validyear;
public:
CNewID(char* name, int yval, int mval, int dval, char* p15, char* p18, int yval2, int mval2, int dval2, int v): COldID(p15, name, yval, mval, dval), issueday(yval2, mval2, dval2), validyear(v)
{
p_id18 = new char[strlen(p18) + 1];
strcpy(p_id18, p18);
}
char* NewNumID()
{
static char num[20];

for (int i = 0; i < 6; i++)
{
num[i] = *(p_id15 + i);
}

if (birthday.getYear() < 2000)
{
num[6] = '1';
num[7] = '9';
}
else
{
num[6] = '2';
num[7] = '0';
}


for (int i = 8; i < 17; i++)
{
num[i] = *(p_id15 + i - 2);
}


int list1[] = {
7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
char list2[12] = {
'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2', '\0' };
int sum = 0;
for (int i = 0; i < 17; i++)
{
sum += ((num[i] - '0') * list1[i]);
}
sum %= 11;
num[17] = list2[sum];
num[18] = '\0';

return num;
}
int valid() {
return ((issueday.getYear() + validyear) > 2017 ||
((issueday.getYear() + validyear) == 2017 && issueday.getMonth() < 5) ||
((issueday.getYear() + validyear) == 2017 && issueday.getMonth() == 5 && issueday.getDay() < 10));

}
bool check()
{
if (strcmp(NewNumID(), p_id18) != 0 || !issueday.check() || !valid())
return 0;

else
return 1;
}
void print()
{
cout << p_id18 << " ";
issueday.print();
if (validyear != 100)
cout << " " << validyear << "年" << endl;
else
cout << " 长期" << endl;
}
~CNewID() {}
};

int main()
{
int t, y1, m1, d1, y2, m2, d2, v;
char name[10], p15[20], p18[20];
cin >> t;
while (t--)
{
cin >> name >> y1 >> m1 >> d1 >> p15 >> p18 >> y2 >> m2 >> d2 >> v;
CNewID c(name, y1, m1, d1, p15, p18, y2, m2, d2, v);
c.COldID::print();
if (c.COldID::check() && c.check())
c.print();
else
cout << "illegal id" << endl;
}
return 0;
}