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:
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)!
Besides the part of the fourth-type operations, some code in this problem is different from 13205 - Happy Ball:
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.
#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; }
#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::move, Array::remove, Array::reverse, List::move, List::remove, List::reverse, and create.
To reduce your coding time, you could refer to the following code :P
#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) { }
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:
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.