深圳大学计软《面向对象的程序设计》实验10 单继承

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

题目描述

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

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

d = ( ( x − x 1 ) 2 + ( y − y 1 ) 2 + ( z − z 1 ) 2 ) 1 2 d = ((x-x_1)^2+(y-y_1)^2+(z-z_1)^2)^{\frac{1} {2}} d=((xx1)2+(yy1)2+(zz1)2)21

输入

第一行二维坐标点位置

第二行三维坐标点位置1

第三行三维坐标点位置2

输出

第一行二维坐标点位置到原点的距离

第二行三维坐标点位置1到原点的距离

第三行三维坐标点位置2到原点的距离

第四行三维坐标点位置2赋值给二维坐标点变量后,二维坐标点到原点的距离

输入样例1

3 4
3 4 5
6 8 8

输出样例1

5
7.07107
12.8062
10

AC代码

#include
#include
using namespace std;

class C2D {
	double x, y;
public:
	C2D(double x = 0, double y = 0) :x(x), y(y) {}
	double getX() { return x; }
	double getY() { return y; }
	double get_distance() {
		return sqrt(x * x + y * y);
	}
};


class C3D :public C2D {
	double z;
public:
	C3D(double x = 0, double y = 0, double z = 0) :C2D(x, y), z(z) {}
	double get_distance() {
		return sqrt(getX() * getX() + getY() * getY() + z * z);
	}
};

int main() {
	double x, y, x1, y1, z1, x2, y2, z2;
	cin >> x >> y >> x1 >> y1 >> z1 >> x2 >> y2 >> z2;

	C2D p(x, y);
	C3D p1(x1, y1, z1), p2(x2, y2, z2);
	C2D p4 = p2;

	cout << p.get_distance() << endl;
	cout << p1.get_distance() << endl;
	cout << p2.get_distance() << endl;
	cout << p4.get_distance() << endl;

}

B. 学生成绩计算(继承和多态)

题目描述

定义Person类具有姓名、年龄等属性,具有输出基本信息的display函数。

选修《面向对象程序设计》课程的学生在Person类的基础上,派生出子类:免听生和非免听生。子类继承父类成员,新增其他成员、改写display函数。

非免听生具有平时成绩、考试成绩和总评成绩三个属性,总评成绩根据(平时成绩40%+考试成绩60%)计算的结果,85分(包含)以上为A,75分(包含)-85分(不包含)为B,65分(包含)-75分(不包含)为C,60分(包含)-65分(不包含)为D,60分(不包含)以下为F。

免听生只有考试成绩和总评成绩两个属性,总评成绩100%根据考试成绩对应上述等级制成绩。

定义上述类并编写主函数,输入类型符号,若输入R,根据学生基本信息、平时成绩和考试成绩,建立非免听生对象,若输入S,根据学生基本信息、考试成绩,建立免听生对象。计算学生的总评成绩,并输出。

输入

测试次数t

随后每行输入学生类型相关信息

输出

每个学生基本信息和总评成绩

输入样例1

2
R cindy 18 100 100
S sandy 28 59

输出样例1

cindy 18 A
sandy 28 F

AC代码

#include
#include
using namespace std;

class Person {
	string name;
	int age;

public:
	Person(string name, int age) :name(name), age(age) {}
	void display() { cout << name << " " << age << " "; }
};


class Student1 :public Person {
	int score1, score2;
	int score;
public:
	Student1(string name, int age, int s1, int s2) :Person(name, age), score1(s1), score2(s2) {
		score = 0.4 * score1 + 0.6 * score2;
	}

	char getGrade() {
		if (score >= 85)
			return 'A';
		if (score >= 75)
			return 'B';
		if (score >= 65)
			return 'C';
		if (score >= 60)
			return 'D';
		return 'F';
	}


	void display() {
		Person::display();
		cout << getGrade() << endl;
	}

};

class Student2 :public Person {
	int score2;
	int score;
public:
	Student2(string name, int age, int s) :Person(name, age), score(s), score2(s) {}
	char getGrade() {
		if (score >= 85)
			return 'A';
		if (score >= 75)
			return 'B';
		if (score >= 65)
			return 'C';
		if (score >= 60)
			return 'D';
		return 'F';
	}


	void display() {
		Person::display();
		cout << getGrade() << endl;
	}

};


int main() {
	int t;
	cin >> t;
	while (t--) {
		char c;
		string name;
		int age;
		cin >> c >> name >> age;
		if (c == 'R') {
			int s1, s2;
			cin >> s1 >> s2;
			Student1(name, age, s1, s2).display();
		}
		else{
			int s;
			cin >> s;
			Student2(name, age, s).display();
		}
	}

	return 0;
}

C. 存折与信用卡(继承)

时间限制
1s
内存限制
128MB

题目描述

定义一个存折类CAccount,存折类具有帐号(account, long)、姓名(name,char[10])、余额(balance,float)等数据成员,可以实现存款(deposit,操作成功提示“saving ok!”)、取款(withdraw,操作成功提示“withdraw ok!”)和查询余额(check)的操作,取款金额必须在余额范围内,否则提示“sorry! over balance!”。

从存折类派生出信用卡类CCreditcard,信用卡类增加了透支限额(limit,float)一项数据成员,对取款操作进行修改,允许在限额范围内透支金额,超出范围取款提示“sorry! over limit!”。注意,在本题中,balance可以是负数,例如当余额为500,可透支金额为500,取款800时,则balance为 - 300。

编写主函数,建立这两个类的对象并测试之。

1.对于存折类,输入账号、姓名、余额后,按照查询余额、存款、查询余额、取款、查询余额的顺序调用类方法并输出。

2.对于信用卡类,输入账号、姓名、余额、透支限额后,按照查询余额、存款、查询余额、取款、查询余额的顺序调用类方法并输出。

输入

账号 姓名 余额

存款金额

取款金额

账号 姓名 余额 透支限额

存款金额

取款金额

输出

账户余额

存款操作结果

账户余额

取款操作结果

账户余额

账户余额

存款操作结果

账户余额

取款操作结果

账户余额

输入样例1

1000 Tom 1000
500
1000
2000 John 500 500
500
1501

输出样例1

balance is 1000
saving ok!
balance is 1500
withdraw ok!
balance is 500
balance is 500
saving ok!
balance is 1000
sorry! over limit!
balance is 1000

AC代码

#include
#include
using namespace std;

class CAccount {
	long account;
	string name;
	double balance;
public:
	CAccount(long account, string name, double balance) :account(account), name(name), balance(balance) {}
	void withdraw(double v) {
		if (v > balance) {
			cout << "sorry! over balance!" << endl;
			return;
		}
		balance -= v;
		cout << "withdraw ok!" << endl;
	}
	void deposit(double v) {
		balance += v;
		cout << "saving ok!" << endl;
	}
	void printBalance() {
		cout << "balance is " << balance << endl;
	}

	double getBalance() { return balance; }
	void setBalance(double v) { balance = v; }

};

class CCreditcard :public CAccount {
	double limit;
public:
	CCreditcard(long account, string name, double balance, double limit) :CAccount(account, name, balance), limit(limit) {}
	void withdraw(double v) {
		if (getBalance() + limit < v) {
			cout << "sorry! over limit!" << endl;
			return;
		}
		setBalance(getBalance() - v);
		cout << "withdraw ok!" << endl;
	}
};


int main() {
	long id, id1;
	string name, name1;
	double v, v1, v2, t;
	cin >> id >> name >> v;
	CAccount c1(id, name, v);
	c1.printBalance();
	cin >> t;
	c1.deposit(t);
	c1.printBalance();
	cin >> t;
	c1.withdraw(t);
	c1.printBalance();

	cin >> id1 >> name1 >> v1 >> v2;
	CCreditcard c2(id1, name1, v1, v2);
	c2.printBalance();
	cin >> t;
	c2.deposit(t);
	c2.printBalance();
	cin >> t;
	c2.withdraw(t);
	c2.printBalance();
	return 0;
}

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

题目描述

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

以CPoint为基类,派生出一个圆形类CCircle,增加数据成员r(半径)和一个计算圆面积的成员函数。

再以CCircle做为直接基类,派生出一个圆柱体类CCylinder,增加数据成员h(高)和一个计算体积的成员函数。

生成圆和圆柱体对象,调用成员函数计算面积或体积并输出结果。

输入

输入圆的圆心位置、半径

输入圆柱体圆心位置、半径、高

输出

输出圆的圆心位置 半径

输出圆面积

输出圆柱体的圆心位置 半径 高

输出圆柱体体积

输入样例1

0 0 1
1 1 2 3

输出样例1

Circle:(0,0),1
Area:3.14
Cylinder:(1,1),2,3
Volume:37.68

AC代码

#include
#include
#include
using namespace std;

class CPoint {
	double x, y;
public:
	CPoint(double x, double y) :x(x), y(y) {}
	double getX() { return x; }
	double getY() { return y; }
	void print() { cout << "(" << getX() << "," << getY() << ")"; }
};

class CCircle :public CPoint {
	double r;
public:
	CCircle(double x, double y, double r) :CPoint(x, y), r(r) {}
	void print() {
		cout << "Circle:";
		CPoint::print();
		cout << ",";
		cout << r << endl;
		cout << "Area:" << getArea() << endl;
	}

	double getArea() {
		return 3.14 * r * r;
	}

	double getR() { return r; }

};

class CCylinder :public CCircle {
	double h;
public:
	CCylinder(double x, double y, double r, double h) :CCircle(x, y, r), h(h) {}

	double getVolume() {
		return h * getArea();
	}

	void print() {
		cout << "Cylinder:";
		CPoint::print();
		cout << "," << getR() << "," << h << endl;
		cout << "Volume:" << getVolume() << endl;
	}
};


int main() {
	double x, y, z, x1, y1, z1, h;
	cin >> x >> y >> z >> x1 >> y1 >> z1 >> h;
	CCircle(x, y, z).print();
	CCylinder(x1, y1, z1, h).print();
	return 0;
}

E. 时钟模拟(继承)

题目描述

定义计数器类,包含保护数据成员value,公有函数increment计数加1。

定义循环计算器继承计数器类,增加私有数据成员:最小值min_value,max_value,

重写公有函数increment,使得value在min_value~max_value区间内循环+1。

定义时钟类,数据成员是私有循环计数器对象小时hour、分钟minute、秒second,公有函数time(int s)计算当前时间经过s秒之后的时间,即hour,minute,second的新value值。

定义时钟类对象,输入当前时间和经过的秒数,调用time函数计算新时间。

根据题目要求,增加必要的构造函数、析构函数和其他所需函数。

因为clock是系统内置函数,为了避免重名,请不要使用clock作为类名或者函数名

输入

第一行测试次数n

2行一组,第一行为当前时间(小时 分钟 秒),第二行为经过的秒数。

输出

输出n行

每行对应每组当前时间和经过秒数后计算得到的新时间(小时:分钟:秒)。

输入样例1

2
8 19 20
20
23 30 0
1801

输出样例1

8:19:40
0:0:1

AC代码

#include
#include
using namespace std;

class Counter {
protected:
	int value;
public:
	Counter(int value = 0) :value(value) {}
	void increment() { value++; }
	void changeValue(int v) { value = v; }
	int getValue() { return value; }
};

class Computer :public Counter {
	int min_value, max_value;
public:
	Computer(int min_value, int max_value, int v = 0) :Counter(v), min_value(min_value), max_value(max_value) {}
	bool increment() { value++; if (value > max_value) { value = min_value; return true; }return false; }
};

class Clock {
	Computer hour, minute, second;
public:
	Clock() :hour(0, 23), minute(0, 59), second(0, 59) {
		int h, m, s;
		cin >> h >> m >> s;
		hour.changeValue(h);
		minute.changeValue(m);
		second.changeValue(s);
	}

	void time(int s = 1) {
		if (s == 0)
			return;
		if (second.increment())
			if (minute.increment())
				hour.increment();
		time(s - 1);
	}
	void print() { cout << hour.getValue() << ":" << minute.getValue() << ":" << second.getValue() << endl; }

};


int main() {
	int n;
	cin >> n;
	while (n--) {
		int hour, minute, second;
		Clock c;
		int t;
		cin >> t;
		c.time(t);
		c.print();
	}
	return 0;
}

F. 新旧身份证(继承)

题目描述

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

class CDate

{

private:

int year, month, day;

public:

CDate(int,int,int);

bool check(); //检验日期是否合法

bool isLeap();

void print();

};

class COldID

{

private:

char *p_id15, *p_name; //15位身份证号码,姓名

CDate birthday; //出生日期

public:

COldID(char *p_idval, char *p_nameval, CDate &day);

bool check(); //验证15位身份证是否合法

void print();

~COldID();

};

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

身份证第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. 确认15位身份证正确.

  2. 确认18位号码是从15位号码扩展的,且第18位校验码正确.

  3. 身份证中的出生日期合法.

  4. 身份证号码中不含非法字符.

  5. 身份证号码的长度正确.

  6. 身份证目前处于有效期内. (2017年5月10日)

输入

测试数据的组数 t

第一个人姓名、出生日期年月日、15位身份证号码、18位身份证号码、签发日期年月日、有效期(100年按长期处理)

第二个人姓名、出生日期年月日、15位身份证号码、18位身份证号码、签发日期年月日、有效期(100年按长期处理)

输出

第一个人姓名

第一个人18位身份证号信息(号码、签发日期和有效期)或"illegal id"

第二个人姓名

第二个人18位身份证号信息(号码、签发日期和有效期)或"illegal id"

输入样例1

10
AAAA 1988 2 28 440301880228113 440301198802281133 2006 1 20 20
BBBB 1997 4 30 440301980808554 440301199808085541 2015 2 2 10
CCCC 1920 5 8 530102200508011 53010219200508011X 1980 3 4 30
DDDD 1980 1 1 340524800101001 340524198001010012 1998 12 11 20
EEEE 1988 11 12 110203881112034 110203198811120340 2007 2 29 20
FFFF 1964 11 15 432831641115081 432831196411150810 2015 8 7 100
GGGG 1996 12 10 44030196121010 44030119961210109 2014 6 7 20
HHHH 1988 7 21 440301880721X12 44030119880721X122 2006 5 11 20
IIII 1976 3 30 440301760330098 440301197603300983 2003 4 15 20
JJJJ 1955 9 5 440301550905205 440301195509051052 2004 6 4 100

输出样例1

AAAA
440301198802281133 2006年1月20日 20年
BBBB
illegal id
CCCC
illegal id
DDDD
illegal id
EEEE
illegal id
FFFF
432831196411150810 2015年8月7日 长期
GGGG
illegal id
HHHH
illegal id
IIII
illegal id
JJJJ
illegal id

AC代码

#include
#include
using namespace std;

class CDate
{
private:
	int year, month, day;
public:
	CDate(int y, int m, int d) :year(y), month(m), day(d) {}
	bool check() {
		int days[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
		if (isLeap())
			days[2] += 1;
		return month >= 1 && month <= 12 && day >= 1 && day <= days[month];
	}

	bool isLeap() {
		if (year % 4 == 0 && year % 100 != 0)
			return true;
		if (year % 400 == 0)
			return true;
		return false;
	}

	void print() {
		cout << year << "年" << month << "月" << day << "日" << " ";
	}


	int getYear() {
		return year;
	}

	int getMonth() {
		return month;
	}

	int getDay() {
		return day;
	}

	string get_8_char() {
		string s1 = to_string(year);
		//s1.erase(0, 2);
		string s2 = to_string(month);
		if (s2.length() == 1)
			s2 = "0" + s2;
		string s3 = to_string(day);
		if (s3.length() == 1)
			s3 = "0" + s2;
		return s1 + s2 + s3;
	}


	string get_6_char() {
		string s = get_8_char();
		return s.substr(2);
	}
};

class COldID
{
private:
	string p_id15, p_name; //15位身份证号码,姓名
	CDate birthday; //出生日期
public:
	COldID(string p_idval, string p_nameval, CDate day) :p_id15(p_idval), p_name(p_nameval), birthday(day) {}
	bool check() {
		return p_id15.find(birthday.get_6_char()) != string::npos;
	}
	void print() { cout << p_id15 << " "; }
	CDate getBirthday() { return birthday; }

	string get18id() {
		string id = p_id15.substr(0, 6) + "19" + p_id15.substr(6);
		int a[] = { 7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2 };
		char b[] = { '1','0','X','9','8','7','6','5','4','3','2' };
		int sum = 0;
		for (int i = 0; i < 17; i++)
			sum += a[i] * (id[i] - '0');
		sum %= 11;
		id.push_back(b[sum]);
		return id;
	}

	string getName() { return p_name; }
};

class CNewID :public COldID {
	string p_id18;
	CDate issueday;
	int validyear;
public:
	CNewID(string name, int year, int month, int day, string id15, string id18, int y, int m, int d, int v)
		:COldID(id15, name, CDate(year, month, day)), p_id18(id18), issueday(y, m, d), validyear(v)
	{}

	bool check() {
		if (p_id18.length() != 18)
			return 0;
		if (!isdigit(p_id18[17]) && p_id18[17] != 'X')
			return 0;
		if (!COldID::check())
			return 0;
		if (get18id() != p_id18) {
			//cout << get18id() << endl;
			//cout << p_id18 << endl;
			return 0;
		}
		if (!getBirthday().check())
			return 0;
		if (!issueday.check())
			return 0;
		for (int i = 0; i < 17; i++)
			if (!isdigit(p_id18[i]))
				return 0;

		if (validyear == 100)
			return 1;

		if (issueday.getYear() + validyear > 2017)
			return 1;
		if (issueday.getYear() + validyear < 2017)
			return 0;

		if (issueday.getMonth() > 5)
			return 1;
		if (issueday.getMonth() < 5)
			return 0;
		if (issueday.getDay() > 10)
			return 1;
		return 0;

	}

	void print() {
		cout << getName() << endl;
		if (!check()) {
			cout << "illegal id" << endl;
			return;
		}
		cout << p_id18 << " ";
		issueday.print();
		if (validyear != 100)
			cout << validyear << "年" << endl;
		else
			cout << "长期\n";
	}

};

int main() {
	int t;
	cin >> t;
	while (t--) {
		string name;
		int y, m, d;
		string id1, id2;
		int y1, m1, d1;
		int valid;
		cin >> name >> y >> m >> d >> id1 >> id2 >> y1 >> m1 >> d1 >> valid;
		CNewID c(name, y, m, d, id1, id2, y1, m1, d1, valid);
		c.print();

	}
	return 0;
}

你可能感兴趣的:(深圳大学,C++程序设计,算法,c++,OJ,开发语言,数据结构)