XMU厦门大学继承和多态实验题
别问是谁写的。不准抄袭!
#include <bits/stdc++.h>
using namespace std;
struct Date{
int Year, Month, Day;
void Print(){ // For Debug
cout << Day << "/" << Month << "/" << Year;
return ;
}
int m1[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // 普通
int m2[13] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // 闰
Date(string s = ""){
this->Year = this->Month = this->Day = 0;
int tmp = 0;
int i = 0;
for(; i < s.length(); i++){
if(s[i] == '/'){
this->Day = tmp;
tmp = 0;
break;
}
tmp = tmp * 10 + s[i] - '0';
}
for(i++; i < s.length(); i++){
if(s[i] == '/'){
this->Month = tmp;
tmp = 0;
break;
}
tmp = tmp * 10 + (s[i] - '0');
}
for(i++; i < s.length(); i++){
tmp = tmp * 10 + s[i] - '0';
}
this->Year = tmp;
}
bool isrun(int year){
if(year % 4 == 0){
if(year % 400 == 0) return 1;
else if(year % 100 == 0) return 0;
else return 1;
}
else return 0;
}
bool operator < (const Date &a) const{
if(Year < a.Year) return 1;
else if(Month < a.Month) return 1;
else if(Day <= a.Day) return 1;
else return 0;
}
int operator - (const Date &a) { // Caculate the days
int ans = 0;
struct Date tmp1 = *this;
struct Date tmp2 = a;
if(tmp1 < a) swap(tmp1, tmp2);
for(int i = tmp1.Year + 1; i < tmp2.Year; i++){
if(Date::isrun(i)) ans += 366;
else ans += 365;
}
for(int i = tmp1.Month + 1; i <= 12; i++){
if(!isrun(tmp1.Year)) ans += m1[i];
else ans += m2[i];
}
if(!isrun(tmp1.Year)) ans += m1[tmp1.Month] - tmp1.Day;
else ans += m2[tmp1.Month] - tmp1.Day;
for(int i = 1; i < tmp2.Month; i++){
if(!isrun(tmp2.Year)) ans += m1[i];
else ans += m2[i];
}
ans += tmp2.Day;
return ans;
}
} ;
class ComputerLab;
class User{
friend ComputerLab;
protected:
string Name;
bool inuse; // already using
public:
int using_Lab;
int using_Computer;
public:
string get_Name(){
return Name;
}
void Change_name(string s){
Name = s;
return ;
}
virtual int get_type(){
return 0;
}
Date Logindate;
} ;
class Student : public User{
friend ComputerLab;
int get_Money(Date &LogoffDate){
int days = LogoffDate - Logindate;
if(days <= 14) return 0;
else return days - 14;
}
virtual int get_type(){
return 1;
}
} ;
class Staff : public User{
friend ComputerLab;
int get_Money(Date &LogoffDate){
int days = LogoffDate - Logindate;
if(days <= 30) return days * 2;
else return 60 + 4 * (days - 30);
}
virtual int get_type(){
return 2;
}
} ;
struct LoginReq{
User *userPoint;
struct Date LoginDate;
int labNum;
int stationNum;
bool flag;
} ;
struct LogoffReq{
User *userPoint;
int Delta_days;
struct Date LogoffDate;
int labNum;
int stationNum;
bool flag;
int Fee; // Money to pay
} ;
set <User*> G; // Users have already appeared
class ComputerLab{
public:
int stationNum;
class Computer{ // Station
public:
bool used; // Being used
string username;
struct Date LoginDate;
void Print_Date(){ // debug
cout << LoginDate.Day << "/" << LoginDate.Month << "/" << LoginDate.Year;
return ;
}
} C[7];
public:
void Print(int now_id){
printf("%d ", now_id);
for(int i = 1; i <= stationNum; i++){
printf("%d: ", i);
if(C[i].used == 0) printf("empty ");
else{
cout << C[i].username << " ";
C[i].Print_Date();
cout << " ";
}
}
cout << endl;
}
void operator + (LoginReq &a){
if(a.stationNum > stationNum){
a.flag = 0;
return ;
}
if(C[a.stationNum].used == 1){
a.flag = 0;
return ;
}
if(a.userPoint->inuse == 1){
a.flag = 0;
return ;
}
a.userPoint->inuse = 1;
C[a.stationNum].used = 1;
C[a.stationNum].username = a.userPoint->get_Name();
a.flag = 1;
a.userPoint->Logindate = a.LoginDate;
C[a.stationNum].LoginDate = a.LoginDate;
a.userPoint->using_Computer = a.stationNum;
a.userPoint->using_Lab = a.labNum;
return ;
}
void operator - (LogoffReq &a){
if(a.stationNum > stationNum){
a.flag = 0;
return ;
}
if(C[a.stationNum].used == 0){
a.flag = 0;
return ;
}
if(a.userPoint->inuse == 0){
a.flag = 0;
return ;
}
int type = a.userPoint->get_type();
int days = a.LogoffDate - a.userPoint->Logindate;
// a.LogoffDate.Print(); cout << " "; a.userPoint->Logindate.Print(); cout << endl;
if(type == 1){
if(days <= 14) a.Fee = 0;
else a.Fee = days - 14;
}
else{
if(days <= 30) a.Fee = 2 * days;
else a.Fee = 60 + 4 * (days - 30);
}
a.Delta_days = days;
a.flag = 1;
a.userPoint->inuse = 0;
C[a.stationNum].used = 0;
C[a.stationNum].username = "";
a.userPoint->Logindate = Date();
return ;
}
} L[5];
int main(){
// freopen("hh.txt", "r", stdin);
string opt, name;
L[1].stationNum = 3;
L[2].stationNum = 4;
L[3].stationNum = 5;
L[4].stationNum = 6;
while(cin >> opt && opt != "="){
cin >> name;
int lab, computer;
if(opt == "+"){
cin >> lab >> computer;
string d; cin >> d;
struct LoginReq tmp;
User *pointer = NULL;
for(auto it : G){
if(it->get_Name() == name){
pointer = it;
break;
}
}
if(pointer == NULL){
if(isdigit(name[0])) pointer = new Staff;
else pointer = new Student;
G.insert(pointer);
pointer->Change_name(name);
}
tmp.labNum = lab;
tmp.stationNum = computer;
tmp.userPoint = pointer;
tmp.LoginDate = Date(d);
if(lab <= 0 || lab >= 5) tmp.flag = 0;
else L[lab] + tmp;
if(tmp.flag == 0) cout << "invalid login" << endl;
for(int i = 1; i <= 4; i++) L[i].Print(i);
cout << endl;
}
else{
string d; cin >> d;
struct LogoffReq tmp;
User *pointer = NULL;
for(auto it : G){
if(it->get_Name() == name){
pointer = it;
break;
}
}
if(pointer == NULL){
tmp.flag = 0;
}
else{
tmp.userPoint = pointer;
tmp.LogoffDate = Date(d);
// cout << "******************" << endl;
// tmp.LogoffDate.Print();
// cout << endl;
tmp.labNum = pointer->using_Lab;
tmp.stationNum = pointer->using_Computer;
L[tmp.labNum] - tmp;
}
if(tmp.flag == 0) cout << "invalid logoff" << endl;
else cout << tmp.userPoint->get_Name() << " log off, " << "time: " << tmp.Delta_days << " days, price: " <<
tmp.Fee << " RMB" << endl;
for(int i = 1; i <= 4; i++) L[i].Print(i);
cout << endl;
}
}
return 0;
}