ENG  RUSTimus Online Judge
Online Judge
Задачи
Авторы
Соревнования
О системе
Часто задаваемые вопросы
Новости сайта
Форум
Ссылки
Архив задач
Отправить на проверку
Состояние проверки
Руководство
Регистрация
Исправить данные
Рейтинг авторов
Текущее соревнование
Расписание
Прошедшие соревнования
Правила
вернуться в форум

Обсуждение задачи 1521. Военные учения 2

Please answer what test#1 looks like. My program crashes while test#1, but all right when i run it on my computer
Послано lenny 16 янв 2012 16:18


my bulky code:


#include <iostream>


class RedBlackTreeWithoutRepeatedElements {

  private:

    static const int BAD_KEY = - 1;

    static enum TypeOfRotation {LEFT, RIGHT};

    static enum NodeColor {RED, BLACK};

    struct Node {

      int key;
      Node *left, *right, *parent;
      NodeColor color;
      int total_number_of_nodes_in_subtree_with_this_node_as_root;

      Node(int m_key) : key(m_key),
                        left(NULL), right(NULL), parent(NULL),
                        color(RED),
                        total_number_of_nodes_in_subtree_with_this_node_as_root(1) {}
    };

    Node *root_, *nil_delimiter;


    void inorderedWalkWithNodeDeletion(Node *node) {
      if ( node != nil_delimiter ) {
        inorderedWalkWithNodeDeletion(node->left);
        Node *root_of_right_subtree = node->right;
        delete node;
        inorderedWalkWithNodeDeletion(root_of_right_subtree);
      }
    }


    void rotate(Node *node, TypeOfRotation type_of_rotation) {

      if ( node == nil_delimiter ) {
        return;
      }

      Node *substitutor_node = (type_of_rotation == LEFT) ? node->right : node->left;
      if ( node == nil_delimiter ) {
        return;
      }

      if ( type_of_rotation == LEFT ) {
        node->right = substitutor_node->left;
        if ( substitutor_node->left != nil_delimiter ) {
          substitutor_node->left->parent = node;
        }
        substitutor_node->left = node;
      }
      else {
        node->left = substitutor_node->right;
        if ( substitutor_node->right != nil_delimiter ) {
          substitutor_node->right->parent = node;
        }
        substitutor_node->right = node;
      }

      substitutor_node->parent = node->parent;
      if ( node != root_ ) {
        if ( node == node->parent->left ) {
          node->parent->left = substitutor_node;
        }
        else {
          node->parent->right = substitutor_node;
        }
      }
      else {
        root_ = substitutor_node;
      }
      node->parent = substitutor_node;

      substitutor_node->total_number_of_nodes_in_subtree_with_this_node_as_root =
        node->total_number_of_nodes_in_subtree_with_this_node_as_root;
      node->total_number_of_nodes_in_subtree_with_this_node_as_root =
        node->left->total_number_of_nodes_in_subtree_with_this_node_as_root +
        node->right->total_number_of_nodes_in_subtree_with_this_node_as_root + 1;
    }


    void correctPropertiesOfRedBlackTreeAfterInsertion(Node *node) {

      while ( node->parent->color == RED ) {

        Node *grandparent_node = node->parent->parent;

        Node *uncle_node = (node->parent == grandparent_node->left) ?
          grandparent_node->right : grandparent_node->left;

        if ( uncle_node->color == RED ) {
          uncle_node->color = node->parent->color = BLACK;
          grandparent_node->color = RED;
          node = grandparent_node;
        }
        else {

          if ( node->parent == grandparent_node->left ) {
            if ( node == node->parent->right ) {
              rotate(node->parent, LEFT);
              node = node->left;
            }
          }
          else {
            if ( node == node->parent->left ) {
              rotate(node->parent, RIGHT);
              node = node->right;
            }
          }

          node->parent->color = BLACK;
          grandparent_node->color = RED;
          rotate(grandparent_node, (node->parent == grandparent_node->left) ? RIGHT : LEFT );
        }
      }

      root_->color = BLACK;
    }


    void correctPropertiesOfRedBlackTreeAfterDelettion(Node *node) {

      while ( node != root_ && node->color == BLACK ) {

        if ( node == node->parent->left ) {

          Node *sibling_node = node->parent->right;

          if ( sibling_node->color == RED ) {
            sibling_node->color = BLACK;
            node->parent->color = RED;
            rotate(node->parent, LEFT);
            sibling_node = node->parent->right;
          }

          if ( sibling_node->left->color == BLACK && sibling_node->right->color == BLACK ) {
            sibling_node->color = RED;
            node = node->parent;
          }
          else {

            if ( sibling_node->right->color == BLACK ) {
              sibling_node->left->color = BLACK;
              sibling_node->color = RED;
              rotate(sibling_node, RIGHT);
              sibling_node = node->parent->right;
            }

            sibling_node->color = node->parent->color;
            node->parent->color = BLACK;
            sibling_node->right->color = BLACK;
            rotate(node->parent, LEFT);
            node = root_;
          }
        }
        else {

          Node *sibling_node = node->parent->left;

          if ( sibling_node->color == RED ) {
            sibling_node->color = BLACK;
            node->parent->color = RED;
            rotate(node->parent, RIGHT);
            sibling_node = node->parent->left;
          }

          if ( sibling_node->left->color == BLACK && sibling_node->right->color == BLACK ) {
            sibling_node->color = RED;
            node = node->parent;
          }
          else {

            if ( sibling_node->left->color == BLACK ) {
              sibling_node->right->color = BLACK;
              sibling_node->color = RED;
              rotate(sibling_node, LEFT);
              sibling_node = node->parent->left;
            }

            sibling_node->color = node->parent->color;
            node->parent->color = BLACK;
            sibling_node->left->color = BLACK;
            rotate(node->parent, RIGHT);
            node = root_;
          }
        }
      }

      node->color = BLACK;
    }


    void removeNode(Node *node) {

      Node *node_to_be_actually_deleted;

      if ( node->left == nil_delimiter || node->right == nil_delimiter ) {
        node_to_be_actually_deleted = node;
      }
      else {
        node_to_be_actually_deleted = node->right;
        while ( node_to_be_actually_deleted->left != nil_delimiter ) {
          node_to_be_actually_deleted = node_to_be_actually_deleted->left;
        }
      }

      --node_to_be_actually_deleted->total_number_of_nodes_in_subtree_with_this_node_as_root;
      Node *current_node = node_to_be_actually_deleted->parent;
      while ( current_node != nil_delimiter ) {
        --current_node->total_number_of_nodes_in_subtree_with_this_node_as_root;
        current_node = current_node->parent;
      }

      Node *only_child_of_node_to_be_actually_deleted =
        (node_to_be_actually_deleted->left != nil_delimiter) ? node_to_be_actually_deleted->left :
                                                               node_to_be_actually_deleted->right;

      only_child_of_node_to_be_actually_deleted->parent =
        node_to_be_actually_deleted->parent;

      if ( node_to_be_actually_deleted->parent != nil_delimiter ) {
        if ( node_to_be_actually_deleted == node_to_be_actually_deleted->parent->left ) {
          node_to_be_actually_deleted->parent->left = only_child_of_node_to_be_actually_deleted;
        }
        else {
          node_to_be_actually_deleted->parent->right = only_child_of_node_to_be_actually_deleted;
        }
      }
      else {
        root_ = only_child_of_node_to_be_actually_deleted;
      }

      if ( node != node_to_be_actually_deleted ) {
        node->key = node_to_be_actually_deleted->key;
      }

      if ( node_to_be_actually_deleted->color == BLACK ) {
        correctPropertiesOfRedBlackTreeAfterDelettion(only_child_of_node_to_be_actually_deleted);
      }

      delete node_to_be_actually_deleted;
    }


    Node* find_k_th_element(int k, Node *root_of_subtree) {

      int r = root_of_subtree->left->total_number_of_nodes_in_subtree_with_this_node_as_root + 1;

      if ( r == k ) {
        return root_of_subtree;
      }
      else if ( r > k ) {
        find_k_th_element(k, root_of_subtree->left);
      }
      else {
        find_k_th_element(k - r, root_of_subtree->right);
      }
    }


  public:

    RedBlackTreeWithoutRepeatedElements() {
      nil_delimiter = new Node(BAD_KEY);
        nil_delimiter->color = BLACK;
        nil_delimiter->left = nil_delimiter->right = nil_delimiter;
        nil_delimiter->total_number_of_nodes_in_subtree_with_this_node_as_root = 0;
      root_ = nil_delimiter;
    }


    void insert(int new_key) {

      if ( root_ == nil_delimiter ) {
        root_ = new Node(new_key);
          root_->color = BLACK;
          root_->left = root_->right = root_->parent = nil_delimiter;
        return;
      }

      Node *current_node = root_, *parent_node = nil_delimiter, *new_node = new Node(new_key);
        new_node->left = new_node->right = nil_delimiter;

      while ( current_node != nil_delimiter ) {
        ++current_node->total_number_of_nodes_in_subtree_with_this_node_as_root;
        parent_node = current_node;
        current_node = (current_node->key > new_key) ? current_node->left : current_node->right;
      }

      if ( parent_node->key > new_key ) {
        parent_node->left = new_node;
      }
      else {
        parent_node->right = new_node;
      }
      new_node->parent = parent_node;

      correctPropertiesOfRedBlackTreeAfterInsertion(new_node);
    }


    int getKeyOfKthElementAndRemoveIt(int k) {
      Node *k_th_element = find_k_th_element(k, root_);
      int key_of_k_th_element = k_th_element->key;
      removeNode(k_th_element);
      return key_of_k_th_element;
    }


    int getSize() const {
      return (root_ != nil_delimiter) ?
        root_->total_number_of_nodes_in_subtree_with_this_node_as_root : 0;
    }


    ~RedBlackTreeWithoutRepeatedElements() {
      inorderedWalkWithNodeDeletion(root_);
      delete nil_delimiter;
    }
};



int main() {

  int number_of_soldiers, number_of_words_in_counting_out_rhyme;

  std::cin >> number_of_soldiers >> number_of_words_in_counting_out_rhyme;

  RedBlackTreeWithoutRepeatedElements soldiers;

  for ( int soldier_id = 1; soldier_id <= number_of_soldiers; ++soldier_id ) {
    soldiers.insert(soldier_id);
  }


   int start_position_for_counting = 1, position_of_excluded_solider;

    while ( soldiers.getSize() > 1 ) {
      position_of_excluded_solider =
        start_position_for_counting + number_of_words_in_counting_out_rhyme - 1;
      if ( position_of_excluded_solider > soldiers.getSize() ) {
        position_of_excluded_solider =
          (number_of_words_in_counting_out_rhyme -
            (soldiers.getSize() - start_position_for_counting + 1)) % soldiers.getSize();
        if ( position_of_excluded_solider == 0 ) {
          position_of_excluded_solider = soldiers.getSize();
        }
      }
      std::cout << soldiers.getKeyOfKthElementAndRemoveIt(position_of_excluded_solider) << " ";
      start_position_for_counting = (position_of_excluded_solider <= soldiers.getSize()) ?
        position_of_excluded_solider : 1;
    }

    std::cout << soldiers.getKeyOfKthElementAndRemoveIt(1);

#if !defined(ONLINE_JUDGE)
  std::cin.ignore(std::cin.rdbuf()->in_avail());
  std::cin.get();
#endif

  return 0;
}


Edited by author 16.01.2012 16:24

Edited by author 16.01.2012 16:39