1. 程式人生 > >在codewars裡升級吧~6:一道3級題程式碼及講解視訊

在codewars裡升級吧~6:一道3級題程式碼及講解視訊

發一期久違的codewars,選了一道3級題。

大專案暫時沒有點子,隨緣吧。

騰訊講解視訊連結

b站講解視訊連結

https://www.bilibili.com/video/av31768767

題 目

THE LIFT

SOLUTION

#include <vector>
#include <string>

bool Isgreater(int i, int j) {
    return i > j;
}

bool Isless(int i, int j) {
    return i < j;
}

class Building {
    std::vector<bool> UpPressed;
    std::vector<bool> DownPressed;
    std::vector<std::vector<int>> Queue;
    size_t NumFloor;

    struct{
        std::vector<bool> LiftFloorTo;
        int Capacity;
        int PeopleInside = 0;
        int FloorAt = 0;
        std::vector<int> Num;
        bool GoingUp = true;
    }Lift;

    int GetNextStop() {
        if(Lift.PeopleInside)
            if (Lift.GoingUp) {
                for (int i = Lift.FloorAt + 1; i < NumFloor; i++) {
                    if (Lift.LiftFloorTo[i] || UpPressed[i])return i;
                }
                throw std::string("Fin");
            }
            else{
                for (int i = Lift.FloorAt - 1; i >= 0; i--) {
                    if (Lift.LiftFloorTo[i] || DownPressed[i])return i;
                }
                throw std::string("Fin");
            }
        else
            if (Lift.GoingUp) {
                for (int i = Lift.FloorAt + 1; i < NumFloor; i++) {
                    if (UpPressed[i])return i;
                }
                Lift.GoingUp = false; 
                for (int i = NumFloor - 1; i >= Lift.FloorAt; i--) {
                    if (DownPressed[i])return i;
                }
                for (int i = Lift.FloorAt - 1; i >= 0; i--) {
                    if (DownPressed[i])return i;
                }
                Lift.GoingUp = true;
                for (int i = 0; i <= Lift.FloorAt; i++) {
                    if (UpPressed[i])return i;
                }
                throw std::string("Fin");
            }
            else {
                for (int i = Lift.FloorAt - 1; i >= 0; i--) {
                    if (DownPressed[i])return i;
                }
                Lift.GoingUp = true;
                for (int i = 0; i <= Lift.FloorAt; i++) {
                    if (UpPressed[i])return i;
                }
                for (int i = Lift.FloorAt + 1; i < NumFloor; i++) {
                    if (UpPressed[i])return i;
                }
                Lift.GoingUp = false;
                for (int i = NumFloor - 1; i >= Lift.FloorAt; i--) {
                    if (DownPressed[i])return i;
                }
                throw std::string("Fin");
            }

    }

public:
    Building(const std::vector<std::vector<int>>& _Queue, int Capacity):
    Queue(_Queue)
    {
        Lift.Capacity = Capacity;
        NumFloor = Queue.size();
        UpPressed.assign(NumFloor, false);
        DownPressed.assign(NumFloor, false);
        for (int FloorNum = 1; FloorNum < NumFloor;FloorNum++) {
            bool UpPressedThisFloor = false;
            bool DownPressedThisFloor = false;
            for(int people:Queue[FloorNum]) {
                if (UpPressedThisFloor&&DownPressedThisFloor) break;
                if (people > FloorNum)UpPressedThisFloor = true;
                else if (people < FloorNum)DownPressedThisFloor = true;
            }
            UpPressed[FloorNum] = UpPressedThisFloor;
            DownPressed[FloorNum] = DownPressedThisFloor;
        }
        Lift.LiftFloorTo.assign(NumFloor, false);
        Lift.Num.assign(NumFloor, 0);
        bool NoNext = false;
        for (auto people = Queue[0].begin(); people != Queue[0].end();) {
            if (NoNext) {
                UpPressed[0] = true;
                break;
            }
            Lift.LiftFloorTo[*people] = true;
            Lift.Num[*people]++;
            Lift.PeopleInside++;
            if (Lift.PeopleInside == Lift.Capacity) {
                NoNext = true;
                UpPressed[0] = false;
            }
            people = Queue[0].erase(people);
        }
        if (!NoNext)UpPressed[0] = false;
    }

    std::vector<int> StartMoving(){
        std::vector<int> floors;
        floors.push_back(0);
        try {
            bool LastIsUp = true;
            while (true) {
                int NextFloor = GetNextStop();
                if (*(floors.end() - 1) != NextFloor) {
                    floors.push_back(NextFloor);
                    Lift.LiftFloorTo[NextFloor] = false;
                    Lift.PeopleInside -= Lift.Num[NextFloor];
                    Lift.Num[NextFloor] = 0;
                    Lift.FloorAt = NextFloor;
                }
                if(Lift.PeopleInside == Lift.Capacity)continue;
                std::vector<bool>& Pressed = Lift.GoingUp ? UpPressed : DownPressed;
                auto Compare = Lift.GoingUp ? &Isgreater: &Isless;
                std::vector<int>& FloorQueue = Queue[NextFloor];
                bool NoNext = false;
                for (auto people = FloorQueue.begin(); people != FloorQueue.end();) {
                    if (Compare(*people,NextFloor)) {
                        if (NoNext) {
                            Pressed[NextFloor] = true;
                            break;
                        }
                        Lift.LiftFloorTo[*people] = true;
                        Lift.Num[*people]++;
                        Lift.PeopleInside++;
                        if (Lift.PeopleInside == Lift.Capacity) {
                            NoNext = true;
                            Pressed[NextFloor] = false;
                        }
                        people = FloorQueue.erase(people);
                        continue;
                    }
                    people++;
                }
                if (!NoNext)Pressed[NextFloor] = false;
                
            }
        }
        catch (std::string fin) {
            if (*(floors.end()-1) == 0)return floors;
            floors.push_back(0);
            return floors;
        }    
        return floors;
    }
};

std::vector<int> the_lift(std::vector<std::vector<int>> queues, int capacity) {
    Building building(queues, capacity);
    return building.StartMoving();
}

int main() {
    std::vector<std::vector<int>> queues; std::vector<int> result;
    queues = { {}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0} };
    auto d = the_lift(queues, 5);
}