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; 
}

posted @ 2023-05-18 21:10  雪之下,树之旁  阅读(55)  评论(0编辑  收藏  举报