Language: C++

#include <stdio.h>
#include <stdint.h>
#include <iostream>
#include <fstream>
#include <cassert>
using namespace std;

//#define DEBUG (1)

#ifdef DEBUG
#define DPRINTF(...)  printf("D(L%d) %s: ", __LINE__, __func__); printf(__VA_ARGS__)
#else
#define DPRINTF(...)
#endif

class Process {
public:
  Process() {};
  Process(string name, int workload);
  ~Process() {};
  int run(int time);
  bool isDone();
  inline string name() { return name_; }
  inline int workload() { return workload_; }
private:
  string name_;
  int workload_;
};

Process::Process(string name, int workload) :
  name_(name),
  workload_(workload) {}

int Process::run(int time)
{
  if (workload_ > time) {
    workload_ -= time;
    return time;
  } else {
    int consume = workload_;
    workload_ -= consume;
    return consume;
  }
}

bool Process::isDone()
{
  return (workload_ <= 0);
}


#if 0
// Ring buffer
// One of issues is that it needs to determine variable data when construting Queue
// Since not appropriate to design queue with ring buffer...
template <class T>
class Queue {
public:
  Queue(int capacity);
  ~Queue();
  void push(T d);
  void pop();
  T front();
  T back();
  bool full();
  bool empty();

private:
  int capacity_;
  T *d_;
  int put_, get_;
};

template <class T>
Queue<T>::Queue(int capacity) :
  capacity_(capacity),
  put_(0),
  get_(0)
{
  d_ = new T[capacity_];
}

template <class T>
Queue<T>::~Queue()
{
  delete [] d_;
}

template <class T>
void Queue<T>::push(T d)
{
  if (full()) {
    cout << "FULL!!" << endl;
    return ;
  }
  d_[put_] = d;
  put_ = (put_ + 1 ) % capacity_;
}

template <class T>
void Queue<T>::pop()
{
  if (empty()) {
    cout << "EMPTY!!" << endl;
    return ;
  }
  get_ = (get_ + 1 ) % capacity_;
}

template <class T>
T Queue<T>::front()
{
  return d_[get_];
}

template <class T>
T Queue<T>::back()
{
  return d_[put_];
}

template <class T>
bool Queue<T>::full()
{
  return get_ = ((put_ + 1) % capacity_);
}

template <class T>
bool Queue<T>::empty()
{
  return (put_ == get_);
}
#endif


template <class T>
struct Node {
  T d_;
  Node<T>* next_;
};

template <class T>
class Queue {
public:
  Queue();
  ~Queue();
  void push(T d);
  void pop();
  T front();
  bool empty();
  void print();
#ifdef DEBUG
public:
#else
private:
#endif
  Node<T>* head_;
};

template <class T>
Queue<T>::Queue()
{
  head_ = nullptr;
}

template <class T>
Queue<T>::~Queue()
{
  Node<T>* current = head_;
  while (current != nullptr) {
    Node<T>* next = current->next_;
    delete current;
    current = next;
  }
}

template <class T>
void Queue<T>::push(T d)
{
  Node<T>* tail = new Node<T>;
  tail->d_ = d;
  tail->next_ = nullptr;

  if (head_ == nullptr) {
    head_ = tail;
    return ;
  }

  Node<T>* node = head_;
  while (node->next_ != nullptr)
    node = node->next_;
  node->next_ = tail;
}

template <class T>
void Queue<T>::pop()
{
  Node<T>* t = head_;
  head_ = head_->next_;
  delete t;
}

template <class T>
T Queue<T>::front()
{
  return head_->d_;
}

template <class T>
bool Queue<T>::empty()
{
  return (head_ == nullptr);
}


int main() {
  int numOfProc, quantum;
  cin >> numOfProc >> quantum;
  DPRINTF("numOfProc : %d\n", numOfProc);
  DPRINTF("quantum: %d\n", quantum);

  Queue<Process> queue;
  for (int i = 0; i < numOfProc; i++) {
    string proc;
    int workload;
    cin >> proc >> workload;
    DPRINTF("process %s, workload %d\n", proc.c_str(), workload);
    queue.push(Process(proc, workload));
  }

#ifdef DEBUG
  {
    DPRINTF("");
    Node<Process> *node = queue.head_;
    while (node != nullptr) {
      if (node != queue.head_) cout << " -> ";
      printf("(%s, %d)", node->d_.name().c_str(), node->d_.workload());
      node = node->next_;
    }
    cout << endl;
  }
#endif // DEBUG

  int time = 0;
  while (!queue.empty()) {
    Process proc = queue.front();
    queue.pop();
    time += proc.run(quantum);
    DPRINTF("TIME: %d, PROC(%s %d)\n", time, proc.name().c_str(), proc.workload());
    if (proc.isDone()) {
      printf("%s %d\n", proc.name().c_str(), time);
    } else {
      queue.push(proc);
    }
  }

  return 0;
}

Mac-mini:study_algorithm_and_data_structure Masa$ vi alds1_3_b.cpp
Mac-mini:study_algorithm_and_data_structure Masa$
Mac-mini:study_algorithm_and_data_structure Masa$
Mac-mini:study_algorithm_and_data_structure Masa$ cat alds1_3_b.cpp
#include <stdio.h>
#include <stdint.h>
#include <iostream>
#include <fstream>
#include <cassert>
using namespace std;

#define RINGBUF (1)
//#define DEBUG (1)

#ifdef DEBUG
#define DPRINTF(...)  printf("D(L%d) %s: ", __LINE__, __func__); printf(__VA_ARGS__)
#else
#define DPRINTF(...)
#endif

class Process {
public:
  Process() {};
  Process(string name, int workload);
  ~Process() {};
  int run(int time);
  bool isDone();
  inline string name() { return name_; }
  inline int workload() { return workload_; }
private:
  string name_;
  int workload_;
};

Process::Process(string name, int workload) :
  name_(name),
  workload_(workload) {}

int Process::run(int time)
{
  if (workload_ > time) {
    workload_ -= time;
    return time;
  } else {
    int consume = workload_;
    workload_ -= consume;
    return consume;
  }
}

bool Process::isDone()
{
  return (workload_ <= 0);
}


#ifdef RINGBUF
// Ring buffer
// One of issues is that it needs to determine variable data when construting Queue
// Since not appropriate to design queue with ring buffer...
template <class T>
class Queue {
public:
  Queue(int capacity);
  ~Queue();
  void push(T d);
  void pop();
  T front();
  bool empty();
  bool full();
private:
  int capacity_;
#ifdef DEBUG
public:
#else //DEBUG
private:
#endif //DEBUG
  T* d_;
  int put_, get_;
};


template <class T>
Queue<T>::Queue(int capacity) :
  capacity_(capacity),
  put_(0),
  get_(0)
{
  d_ = new T[capacity_];
}

template <class T>
Queue<T>::~Queue()
{
  delete [] d_;
}

template <class T>
void Queue<T>::push(T d)
{
  if (full()) {
    cout << "FULL!!" << endl;
    return ;
  }
  d_[put_] = d;
  put_ = (put_ + 1 ) % capacity_;
}

template <class T>
void Queue<T>::pop()
{
  if (empty()) {
    cout << "EMPTY!!" << endl;
    return ;
  }
  get_ = (get_ + 1 ) % capacity_;
}

template <class T>
T Queue<T>::front()
{
  return d_[get_];
}

template <class T>
bool Queue<T>::full()
{
  return get_ == ((put_ + 1) % capacity_);
}

template <class T>
bool Queue<T>::empty()
{
  return (put_ == get_);
}
#endif //RINGBUF


#ifdef LINKED_LIST
template <class T>
struct Node {
  T d_;
  Node<T>* next_;
};

template <class T>
class Queue {
public:
  Queue();
  ~Queue();
  void push(T d);
  void pop();
  T front();
  bool empty();
  void print();
#ifdef DEBUG
public:
#else
private:
#endif
  Node<T>* head_;
};

template <class T>
Queue<T>::Queue()
{
  head_ = nullptr;
}

template <class T>
Queue<T>::~Queue()
{
  Node<T>* current = head_;
  while (current != nullptr) {
    Node<T>* next = current->next_;
    delete current;
    current = next;
  }
}

template <class T>
void Queue<T>::push(T d)
{
  Node<T>* tail = new Node<T>;
  tail->d_ = d;
  tail->next_ = nullptr;

  if (head_ == nullptr) {
    head_ = tail;
    return ;
  }

  Node<T>* node = head_;
  while (node->next_ != nullptr)
    node = node->next_;
  node->next_ = tail;
}

template <class T>
void Queue<T>::pop()
{
  Node<T>* t = head_;
  head_ = head_->next_;
  delete t;
}

template <class T>
T Queue<T>::front()
{
  return head_->d_;
}

template <class T>
bool Queue<T>::empty()
{
  return (head_ == nullptr);
}
#endif //LINKED_LIST


int main() {
  int numOfProc, quantum;
  cin >> numOfProc >> quantum;
  DPRINTF("numOfProc : %d\n", numOfProc);
  DPRINTF("quantum: %d\n", quantum);

#ifdef RINGBUF
  const int MAX_NUM_OF_PROC = 10000;
  Queue<Process> queue(MAX_NUM_OF_PROC);
#endif //RINGBUF
#ifdef LINKED_LIST
  Queue<Process> queue;
#endif // LINKED_LIST

  for (int i = 0; i < numOfProc; i++) {
    string proc;
    int workload;
    cin >> proc >> workload;
    DPRINTF("process %s, workload %d\n", proc.c_str(), workload);
    queue.push(Process(proc, workload));
  }

#ifdef DEBUG
#ifdef RINGBUF
  {
    if (queue.put_ > queue.get_) {
      for (int i = queue.get_; i < queue.put_; i++) {
        Process *proc = &queue.d_[i];
        DPRINTF("process %s, workload %d\n",
            proc->name().c_str(), proc->workload());
      }
    }
  }
#endif //RINGBUF
#ifdef LINKED_LIST
  {
    DPRINTF("");
    Node<Process> *node = queue.head_;
    while (node != nullptr) {
      if (node != queue.head_) cout << " -> ";
      printf("(%s, %d)", node->d_.name().c_str(), node->d_.workload());
      node = node->next_;
    }
    cout << endl;
  }
#endif //LINKED_LIST
#endif //DEBUG

  int time = 0;
  while (!queue.empty()) {
    Process proc = queue.front();
    queue.pop();
    time += proc.run(quantum);
    DPRINTF("TIME: %d, PROC(%s %d)\n", time, proc.name().c_str(), proc.workload());
    if (proc.isDone()) {
      printf("%s %d\n", proc.name().c_str(), time);
    } else {
      queue.push(proc);
    }
  }

  return 0;
}

Compiler output:
a.cc:260:1: error: 'Mac' does not name a type
  260 | Mac-mini:study_algorithm_and_data_structure Masa$ vi alds1_3_b.cpp
      | ^~~
a.cc:280:7: error: redefinition of 'class Process'
  280 | class Process {
      |       ^~~~~~~
a.cc:16:7: note: previous definition of 'class Process'
   16 | class Process {
      |       ^~~~~~~
a.cc:294:1: error: redefinition of 'Process::Process(std::string, int)'
  294 | Process::Process(string name, int workload) :
      | ^~~~~~~
a.cc:30:1: note: 'Process::Process(std::string, int)' previously defined here
   30 | Process::Process(string name, int workload) :
      | ^~~~~~~
a.cc:298:5: error: redefinition of 'int Process::run(int)'
  298 | int Process::run(int time)
      |     ^~~~~~~
a.cc:34:5: note: 'int Process::run(int)' previously defined here
   34 | int Process::run(int time)
      |     ^~~~~~~
a.cc:310:6: error: redefinition of 'bool Process::isDone()'
  310 | bool Process::isDone()
      |      ^~~~~~~
a.cc:46:6: note: 'bool Process::isDone()' previously defined here
   46 | bool Process::isDone()
      |      ^~~~~~~
a.cc:321:7: error: redefinition of 'class Queue<T>'
  321 | class Queue {
      |       ^~~~~
a.cc:143:7: note: previous definition of 'class Queue<T>'
  143 | class Queue {
      |       ^~~~~
a.cc:343:1: error: no declaration matches 'Queue<T>::Queue(int)'
  343 | Queue<T>::Queue(int capacity) :
      | ^~~~~~~~
a.cc:161:1: note: candidate is: 'Queue<T>::Queue()'
  161 | Queue<T>::Queue()
      | ^~~~~~~~
a.cc:143:7: note: 'class Queue<T>' defined here
  143 | class Queue {
      |       ^~~~~
a.cc:352:1: error: redefinition of 'Queue<T>::~Queue()'
  352 | Queue<T>::~Queue()
      | ^~~~~~~~
a.cc:167:1: note: 'Queue<T>::~Queue()' previously declared here
  167 | Queue<T>::~Queue()
      | ^~~~~~~~
a.cc:358:6: error: redefinition of 'void Queue<T>::push(T)'
  358 | void Queue<T>::push(T d)
      |      ^~~~~~~~
a.cc:178:6: note: 'void Queue<T>::push(T)' previously declared here
  178 | void Queue<T>::push(T d)
      |      ^~~~~~~~
a.cc:369:6: error: redefinition of 'void Queue<T>::pop()'
  369 | void Queue<T>::pop()
      |      ^~~~~~~~
a.cc:196:6: note: 'void Queue<T>::pop()' previously declared here
  196 | void Queue<T>::pop()
      |      ^~~~~~~~
a.cc:379:3: error: redefinition of 'T Queue<T>::front()'
  379 | T Queue<T>::front()
      |   ^~~~~~~~
a.cc:204:3: note: 'T Queue<T>::front()' previously declared here
  204 | T Queue<T>::front()
      |   ^~~~~~~~
a.cc:385:6: error: no declaration matches 'bool Queue<T>::full()'
  385 | bool Queue<T>::full()
      |      ^~~~~~~~
a.cc:385:6: note: no functions named 'bool Queue<T>::full()'
a.cc:143:7: note: 'class Queue<T>' defined here
  143 | class Queue {
      |       ^~~~~
a.cc:391:6: error: redefinition of 'bool Queue<T>::empty()'
  391 | bool Queue<T>::empty()
      |      ^~~~~~~~
a.cc:210:6: note: 'bool Queue<T>::empty()' previously declared here
  210 | bool Queue<T>::empty()
      |      ^~~~~~~~
a.cc:480:5: error: redefinition of 'int main()'
  480 | int main() {
      |     ^~~~
a.cc:216:5: note: 'int main()' previously defined here
  216 | int main() {
      |     ^~~~
a.cc: In function 'int main()':
a.cc:488:39: error: no matching function for call to 'Queue<Process>::Queue(const int&)'
  488 |   Queue<Process> queue(MAX_NUM_OF_PROC);
      |                                       ^
a.cc:161:1: note: candidate: 'Queue<T>::Queue() [with T = Process]'
  161 | Queue<T>::Queue()
      | ^~~~~~~~
a.cc:161:1: note:   candidate expects 0 arguments, 1 provided
a.cc:143:7: note: candidate: 'constexpr Queue<Process>::Queue(const Queue<Process>&)'
  143 | class Queue {
      |       ^~~~~
a.cc:143:7: note:   no known conversion for argument 1 from 'const int' to 'const Queue<Process>&'