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

#include <algorithm>
#include <iostream>
#include <vector>

struct Character {
  int health;
  int attack;
  int defence;
  int speed;
};

struct Enemy : public Character {
  bool defeatable;
  unsigned long long dameges_per_turn;
  unsigned long long turns_for_beat;

  Enemy() : defeatable(true) {}
};

std::istream &operator>>(std::istream &stream, Character &character) {
  return (stream >> character.health >> character.attack >> character.defence >>
          character.speed);
}

int main() {
  // read length of enemies
  int enemy_length;
  std::cin >> enemy_length;

  // read player data
  Character player;
  std::cin >> player;

  // read enemies data
  std::vector<Enemy> enemies(enemy_length);
  for (auto &enemy : enemies)
    std::cin >> enemy;

  // calculate enemies extra data
  for (auto &enemy : enemies) {
    // calculate dameges
    int damage_for_enemy = player.attack - enemy.defence;
    int damage_for_player = enemy.attack - player.defence;

    // turns_for_beat
    if (damage_for_enemy <= 0)
      enemy.defeatable = false;
    else
      enemy.turns_for_beat = enemy.health / damage_for_enemy +
                             (enemy.health % damage_for_enemy ? 1 : 0);

    // damages_per_turn
    enemy.dameges_per_turn = damage_for_player > 0 ? damage_for_player : 0;

    // cannot defeat this enemy no matter how
    if (!enemy.defeatable && enemy.dameges_per_turn > 0) {
      std::cout << -1 << std::endl;
      return 0;
    }
  }

  // erase immortal but harmless enemies
  enemies.erase(
      std::remove_if(enemies.begin(), enemies.end(),
                     [](const Enemy &enemy) { return !(enemy.defeatable); }),
      enemies.end());

  // sort enemies by order to defeat
  std::sort(enemies.begin(), enemies.end(),
            [](const Enemy &lhs, const Enemy &rhs) {
              return (rhs.dameges_per_turn * lhs.turns_for_beat) <
                     (lhs.dameges_per_turn * rhs.turns_for_beat);
            });

  // surprise attack by enemy
  unsigned long long total_damages = 0;
  for (auto &enemy : enemies)
    if (player.speed < enemy.speed)
      total_damages += enemy.dameges_per_turn;

  // fight simulation
  unsigned long long total_turns = 0;
  for (auto &enemy : enemies) {
    total_turns += enemy.turns_for_beat;
    total_damages += enemy.dameges_per_turn * (total_turns - 1);

    // player lose test
    if (player.health <= total_damages) {
      std::cout << -1 << std::endl;
      return 0;
    }
  }

  // result
  std::cout << total_damages << std::endl;
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <vector>

struct Character {
  int health;
  int attack;
  int defence;
  int speed;
};

struct Enemy : public Character {
  bool defeatable;
  unsigned long long dameges_per_turn;
  unsigned long long turns_for_beat;

  Enemy() : defeatable(true) {}
};

std::istream &operator>>(std::istream &stream, Character &character) {
  return (stream >> character.health >> character.attack >> character.defence >>
          character.speed);
}

int main() {
  // read length of enemies
  int enemy_length;
  std::cin >> enemy_length;

  // read player data
  Character player;
  std::cin >> player;

  // read enemies data
  std::vector<Enemy> enemies(enemy_length);
  for (auto &enemy : enemies)
    std::cin >> enemy;

  // calculate enemies extra data
  for (auto i = enemies.begin(); i != enemies.end();) {
    // get reference
    Enemy &enemy = *i;

    // calculate dameges
    int damage_for_enemy = player.attack - enemy.defence;
    int damage_for_player = enemy.attack - player.defence;

    // turns_for_beat
    if (damage_for_enemy <= 0)
      enemy.defeatable = false;
    else
      enemy.turns_for_beat = enemy.health / damage_for_enemy +
                             (enemy.health % damage_for_enemy ? 1 : 0);

    // damages_per_turn
    enemy.dameges_per_turn = damage_for_player > 0 ? damage_for_player : 0;

    // undefeatable check
    if (!enemy.defeatable) {
      if (enemy.dameges_per_turn > 0) {
        // cannot defeat this enemy no matter how
        std::cout << -1 << std::endl;
        return 0;
      } else {
        // this enemy is immortal but harmless
        i = enemies.erase(i);
        continue;
      }
    }

    // increment here for the valid erase() of enemies
    i++;
  }

  // sort enemies by order to defeat
  std::sort(enemies.begin(), enemies.end(),
            [](const Enemy &lhs, const Enemy &rhs) {
              return (rhs.dameges_per_turn * lhs.turns_for_beat) <
                     (lhs.dameges_per_turn * rhs.turns_for_beat);
            });

  // surprise attack by enemy
  unsigned long long total_damages = 0;
  for (auto &enemy : enemies)
    if (player.speed < enemy.speed)
      total_damages += enemy.dameges_per_turn;

  // fight simulation
  unsigned long long total_turns = 0;
  for (auto &enemy : enemies) {
    total_turns += enemy.turns_for_beat;
    total_damages += enemy.dameges_per_turn * (total_turns - 1);

    // player lose test
    if (player.health <= total_damages) {
      std::cout << -1 << std::endl;
      return 0;
    }
  }

  // result
  std::cout << total_damages << std::endl;
  return 0;
}