Problem p02265 (C++) — buggy submission, verdict: Time Limit Exceeded

//
//  4.cpp
//  Algorithms and Data Structures
//
//  Created by kawauso on 2018/04/06.
//

#include <cassert>
#include <iostream>
#include <queue>
#include <sstream>
#include <string>
#include <tuple>
#include <vector>

void c_4_2();
void c_4_3();
void c_4_4();

#define MAIN() c_4_4()
#ifdef MAIN
int main(int argc, const char *argv[]) {
  std::ios::sync_with_stdio(false);
  MAIN();
  return 0;
}
#else
#include "4.hpp"
#endif

class Item {
public:
  Item *next;
  Item *prev;
  int key;
};

void c_4_4() {
  int n;
  Item *first;
  Item *last;
  Item *curr;

  std::cin >> n;
  first = NULL;
  last = NULL;
  for (int i = 0; i < n; i++) {
    std::string command;

    std::cin >> command;
    if (command == "insert") {
      int key;

      std::cin >> key;
      auto newItem = new Item();
      newItem->key = key;
      newItem->next = first;
      if (first != NULL) {
        first->prev = newItem;
      }
      first = newItem;
      if (last == NULL) {
        last = newItem;
      }
    } else if (command == "delete") {
      int key;
      Item *curr;

      std::cin >> key;
      curr = first;
      while (1) {
        if (curr->key == key) {
          if (curr == last) {
            last = curr->prev;
          } else {
            curr->next->prev = curr->prev;
          }
          if (curr == first) {
            first = curr->next;
          } else {
            curr->prev->next = curr->next;
          }
          delete curr;
          break;
        }
        if (curr == last) {
          break;
        }
        curr = curr->next;
      }
    } else if (command == "deleteFirst") {
      const auto curr = first;
      if (curr == last) {
        last = NULL;
        first = NULL;
      } else {
        first = curr->next;
      }
      delete curr;
    } else if (command == "deleteLast") {
      const auto curr = last;
      if (curr == first) {
        first = NULL;
        last = NULL;
      } else {
        last = curr->prev;
      }
      delete curr;
    } else {
      assert(false);
    }
  }

  curr = first;
  while (1) {
    if (curr != first) {
      std::cout << " ";
    }
    std::cout << curr->key;
    if (curr == last) {
      break;
    }
    curr = curr->next;
  }
  std::cout << std::endl;
}

void c_4_3() {
  int n;
  int q;
  int elapsed;

  std::cin >> n;
  std::cin >> q;
  std::queue<std::tuple<std::string, int>> queue;
  for (int i = 0; i < n; i++) {
    std::string name;
    int time;

    std::cin >> name;
    std::cin >> time;
    queue.push(std::make_tuple(name, time));
  }
  elapsed = 0;
  while (queue.size() > 0) {
    int min_qt;

    min_qt = 0;
    for (int i = 0; i < queue.size(); i++) {
      std::tuple<std::string, int> p;

      p = queue.front();
      queue.pop();
      if (std::get<1>(p) <= q) {
        // the process ends
        elapsed += std::get<1>(p);
        std::cout << std::get<0>(p) << " " << elapsed << std::endl;
        continue;
      }
      std::get<1>(p) -= q;
      queue.push(p);
      elapsed += q;
      if (min_qt == 0 || min_qt > std::get<1>(p)) {
        min_qt = std::get<1>(p);
      }
    }
  }
}
// 難しかった点:
// vectorでqueueを実現しようとして処理時間が長過ぎ、いろいろ工夫をするも改善せず、std::queueを利用したら1000分の1以下になった
// 正解との違い: queueをリングバッファーで手作りしていない

void c_4_2() {
  std::string line;
  std::string s;

  // input
  std::getline(std::cin, line);
  std::istringstream iss(line);
  std::vector<std::string> a;
  while (iss >> s) {
    if (s == "+") {
      const auto result = std::stoi(a[1]) + std::stoi(a[0]);
      a.erase(a.begin(), a.begin() + 2);
      a.insert(a.begin(), std::to_string(result));
    } else if (s == "-") {
      const auto result = std::stoi(a[1]) - std::stoi(a[0]);
      a.erase(a.begin(), a.begin() + 2);
      a.insert(a.begin(), std::to_string(result));
    } else if (s == "*") {
      const auto result = std::stoi(a[1]) * std::stoi(a[0]);
      a.erase(a.begin(), a.begin() + 2);
      a.insert(a.begin(), std::to_string(result));
    } else {
      a.insert(a.begin(), s);
    }
  }
  std::cout << a[0] << std::endl;
}
// 正解との相違: 演算子は格納しなくてよいので配列の要素の型は整数でよい
// C++で実装するならstd::stackを使ってよいだろう


Error: TLE

Fixed submission:

//
//  4.cpp
//  Algorithms and Data Structures
//
//  Created by kawauso on 2018/04/06.
//

#include <cassert>
#include <iostream>
#include <queue>
#include <sstream>
#include <string>
#include <tuple>
#include <vector>

void c_4_2();
void c_4_3();
void c_4_4();

#define MAIN() c_4_4()
#ifdef MAIN
int main(int argc, const char *argv[]) {
  std::ios::sync_with_stdio(false);
  MAIN();
  return 0;
}
#else
#include "4.hpp"
#endif

class Item {
public:
  Item *next;
  Item *prev;
  int key;
};

void c_4_4() {
  int n;
  Item *first;
  Item *last;
  Item *curr;

  std::cin >> n;
  first = NULL;
  last = NULL;
  for (int i = 0; i < n; i++) {
    std::string command;

    std::cin >> command;
    if (command == "insert") {
      int key;

      std::cin >> key;
      auto newItem = new Item();
      newItem->key = key;
      newItem->next = first;
      if (first != NULL) {
        first->prev = newItem;
      }
      first = newItem;
      if (last == NULL) {
        last = newItem;
      }
    } else if (command == "delete") {
      int key;
      Item *curr;

      std::cin >> key;
      curr = first;
      while (1) {
        if (curr->key == key) {
          if (curr == last) {
            last = curr->prev;
          } else {
            curr->next->prev = curr->prev;
          }
          if (curr == first) {
            first = curr->next;
          } else {
            curr->prev->next = curr->next;
          }
          delete curr;
          break;
        }
        if (curr == last) {
          break;
        }
        curr = curr->next;
      }
    } else if (command == "deleteFirst") {
      const auto curr = first;
      first = curr->next;
      if (first == NULL) {
        last = NULL;
      }
      delete curr;
    } else if (command == "deleteLast") {
      const auto curr = last;
      last = curr->prev;
      if (last == NULL) {
        first = NULL;
      }
      delete curr;
    } else {
      assert(false);
    }
  }

  curr = first;
  while (1) {
    if (curr != first) {
      std::cout << " ";
    }
    std::cout << curr->key;
    if (curr == last) {
      break;
    }
    curr = curr->next;
  }
  std::cout << std::endl;
}

void c_4_3() {
  int n;
  int q;
  int elapsed;

  std::cin >> n;
  std::cin >> q;
  std::queue<std::tuple<std::string, int>> queue;
  for (int i = 0; i < n; i++) {
    std::string name;
    int time;

    std::cin >> name;
    std::cin >> time;
    queue.push(std::make_tuple(name, time));
  }
  elapsed = 0;
  while (queue.size() > 0) {
    int min_qt;

    min_qt = 0;
    for (int i = 0; i < queue.size(); i++) {
      std::tuple<std::string, int> p;

      p = queue.front();
      queue.pop();
      if (std::get<1>(p) <= q) {
        // the process ends
        elapsed += std::get<1>(p);
        std::cout << std::get<0>(p) << " " << elapsed << std::endl;
        continue;
      }
      std::get<1>(p) -= q;
      queue.push(p);
      elapsed += q;
      if (min_qt == 0 || min_qt > std::get<1>(p)) {
        min_qt = std::get<1>(p);
      }
    }
  }
}
// 難しかった点:
// vectorでqueueを実現しようとして処理時間が長過ぎ、いろいろ工夫をするも改善せず、std::queueを利用したら1000分の1以下になった
// 正解との違い: queueをリングバッファーで手作りしていない

void c_4_2() {
  std::string line;
  std::string s;

  // input
  std::getline(std::cin, line);
  std::istringstream iss(line);
  std::vector<std::string> a;
  while (iss >> s) {
    if (s == "+") {
      const auto result = std::stoi(a[1]) + std::stoi(a[0]);
      a.erase(a.begin(), a.begin() + 2);
      a.insert(a.begin(), std::to_string(result));
    } else if (s == "-") {
      const auto result = std::stoi(a[1]) - std::stoi(a[0]);
      a.erase(a.begin(), a.begin() + 2);
      a.insert(a.begin(), std::to_string(result));
    } else if (s == "*") {
      const auto result = std::stoi(a[1]) * std::stoi(a[0]);
      a.erase(a.begin(), a.begin() + 2);
      a.insert(a.begin(), std::to_string(result));
    } else {
      a.insert(a.begin(), s);
    }
  }
  std::cout << a[0] << std::endl;
}
// 正解との相違: 演算子は格納しなくてよいので配列の要素の型は整数でよい
// C++で実装するならstd::stackを使ってよいだろう