13207 - Happy Ball - Reverse   

Description

This is a partial judge problem OwO

There are  people in a row. From left to right, they are numbered from 1 to . The happy value of the -th person is . And there is a ball which is carried by the first person in the beginning. Now they want to play a game called "SAO".

In this game they need to execute  operations. There are 4 types of operations:

  1. The person who is carrying the ball need to speak out his/her happy value loudly.
  2. The person who is carrying the ball passes the ball to the person on the left side(or right side). This will last  times. The passing direction(i.e to left or to right) will be given and is fixed in one operation. Stop passing if no one is on the corresponding side of the person who is carrying the ball.
  3. The person who is carrying the ball leave the row. Before leaving, he/she would pass the ball to the person on the right side(or left side if no one is on the right side).
  4. Reverse the order of all the people in the row. The one who is carrying the ball just keeps carrying the ball.

This game looks not funny, right?

Anyway, you need to write a program to simulate this game. For each first-type operation, output the happy value of the person who is carrying the ball. In this problem, there is a special constraint: the number of second-type operations times the number of third-type operations is less than or equal to Q.

Solve this problem with array and/or linked list(maintaining the people in the row and who is carrying the ball)!

Note

Besides the part of the fourth-type operations, some code in this problem is different from 13205 - Happy Ball:

  1. some parameters of create function
  2. the access modifiers of member variable of List class
  3. remove function of List class

​Trace function.h for more detail.

 

In the following code, nullptr is just like NULL in C. You could treat them as the same.

But nullptr is only available in C++11 and beyond. So compiling/submitting your code in C++11 or beyond.

Partial Code

main.cpp

#include <iostream>
#include "function.h"
using namespace std;
int main() {
    /* I/O optimization */
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int t;
    cin >> t;
    while(t--) {
        int n;
        cin >> n;
        int *arr = new int[n + 1];
        for(int i=1;i<=n;i++)    cin >> arr[i];

        int q;
        cin >> q;
        Operation *ops = new Operation[q + 1];
        int op2Cnt = 0, op3Cnt = 0;
        for(int i=1;i<=q;i++) {
            cin >> ops[i].type;

            if(ops[i].type == 2) {
                cin >> ops[i].d;
                op2Cnt++;
            }
            else if(ops[i].type == 3) {
                op3Cnt++;
            }
        }

        ContainerBase *solver = create(n, arr, op2Cnt, op3Cnt);
        for(int i=1;i<=q;i++) {
            if(ops[i].type == 1)
                cout << solver->print() << '\n';
            else if(ops[i].type == 2)
                solver->move(ops[i].d);
            else if(ops[i].type == 3)
                solver->remove();
            else
                solver->reverse();
        }

        delete[] arr;
        delete[] ops;
        delete solver;
    }
    return 0;
}

function.h

#ifndef FUNCTION_H
#define FUNCTION_H

/* an abstract class for the container used in this problem */
class ContainerBase {
    public:
        /* for the first-type operation */
        virtual int print() = 0;
        /* for the second-type operation */
        virtual void move(int) = 0;
        /* for the third-type operation */
        virtual void remove() = 0;
        /* for the fourth-type operation */
        virtual void reverse() = 0;
        int getSize() { return size; }

        virtual ~ContainerBase() {}
    protected:
        int size;    // the number of elements(people) in the container
        bool rev;    // record whether the row need to be reversed or not
};

/* array class deriving from ContainerBase */
class Array final : public ContainerBase {
    public:
        Array() {}
        Array(int n, int *arr) {
            size = n;

            mem = new int[size + 1];
            for(int i=1;i<=size;i++)    mem[i] = arr[i];
            cur = 1;

            rev = false;
        }

        virtual int print() override { return mem[cur]; }
        /* TODO */
        virtual void move(int) override;
        /* TODO */
        virtual void remove() override;
        /* TODO */
        virtual void reverse() override;

        ~Array() { delete[] mem; }
    private:
        int *mem;    // array for maintaining all the elements(the happy value of all the people)
        int cur;    // record who is carrying the ball
};

/* doubly linked list class deriving from ContainerBase */
class List final : public ContainerBase {
    public:
        List() {}
        List(int n, int *arr) {
            size = n;

            cur = new Node(arr[1]);
            Node *back = cur;
            for(int i=2;i<=n;i++) {
                Node *newNode = new Node(arr[i]);
                back->insertBack(newNode);
                back = newNode;
            }

            rev = false;
        }

        virtual int print() override { return cur->val; }
        /* TODO */
        virtual void move(int) override;
        /* TODO */
        virtual void remove() override;
        /* TODO */
        virtual void reverse() override;

        ~List() { for(int i=1;i<=size;i++)    cur = cur->remove(); }
    private:
        /* nested class for the node in linked list */
        class Node {
            public:
                Node *pre, *nxt;
                int val;

                Node() {}
                Node(int newVal) : pre(nullptr), nxt(nullptr), val(newVal) {}
                /* insert a new node after the current node */
                void insertBack(Node *newNode) {
                    nxt = newNode;
                    newNode->pre = this;
                }
                /* remove the current node and return the next node(or the previous node if the next node doesn't exist) */
                Node* remove(bool preFirst=false) {
                    Node *ret = (nxt == nullptr ? pre : nxt);
                    if(preFirst && pre != nullptr)    ret = pre;
                    if(pre != nullptr)    pre->nxt = nxt;
                    if(nxt != nullptr)    nxt->pre = pre;
                    delete this;
                    return ret;
                }
        } *cur;    // record who is carrying the ball
};

/* a class for operation */
class Operation {
    public:
        int type,d;
};

/* TODO: create array/linked list based on the number of the second-type and the third-type operations. then return it */
ContainerBase* create(int, int*, int, int);

#endif

Implement the seven functions: Array::moveArray::removeArray::reverseList::moveList::remove, List::reverse, and create.

 

To reduce your coding time, you could refer to the following code :P

function.cpp

#include "function.h"

void Array::move(int d) {
}

void Array::remove() {
}

void Array::reverse() {
}

void List::move(int d) {
}

void List::remove() {
}

void List::reverse() {
}

ContainerBase* create(int n, int *arr, int op2Cnt, int op3Cnt) {
}

Input

The very first line contains an integer  – the number of tasks.

The first line of each task contains an integer  – the number of people in the beginning.

The second line contains  integers  – the happy value of all the people.

The third line contains an integer  – the number of operations excuted.

Then  lines follow. The -th line of each task contains an integer  – the type of the -th operation. If  is equal to 2, then an integer  follows. The passing direction of a second-type operation is right when its  is positive or left otherwise. The number of second-type operations times the number of third-type operations is less than or equal to Q.

 

It's guaranteed that:

  • The 1st testcase must be identical to the Sample #1 below
  • For the first 4 testcases: the number of fourth-type operations = 0
  • For the first 8 testcases: the number of fourth-type operations ≤ 50

Output

For each task, output one line which represents the happy value of who is carrying ball for every first-type operation.

 

Note: there are two sample below. "# Sample Input 1/2" and "# Sample Output 1/2" are not the part of input and output.

They are just for marking that the following content corresponds to which sample.

Sample Input  Download

Sample Output  Download

Partial Judge Code

13207.cpp

Partial Judge Header

13207.h

Tags




Discuss