Cod sursa(job #770877)

Utilizator GagosGagos Radu Vasile Gagos Data 24 iulie 2012 00:42:02
Problema Elementul majoritar Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.65 kb
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>

#define NODEBUG

#ifndef DEBUG
#define INIT_VAL 151007
#else
#define INIT_VAL 11
#endif

class HashTable {
 public:
  struct Node {
    int val;
    int count;
    Node* next;
    
    Node(int val, int count, Node* next);
  };

  HashTable();
  ~HashTable() { }

  int size();
  Node* get_max();
  Node* operator[](const int& index) const;
  void operator<<(const int& val);
  void rehash();

 private:
  int dim_;
  int count_;
  int threshold_;
  Node* max_;
  Node** table_;
  
  void reset_table();
};

HashTable::Node::Node(int val, int count, Node* next) 
  : val(val), count(count), next(next) { }

HashTable::HashTable() : dim_(INIT_VAL), count_(0) {
  this->table_ = new Node*[this->dim_];
  this->threshold_ = this->dim_ * 0.75;
  this->reset_table();
  this->max_ = new Node(-1, -1, NULL);
}

int HashTable::size() {
  return this->dim_;
}

void HashTable::operator<<(const int& val) {
  int index = val % this->dim_;
  
  for (Node* el = this->table_[index]; el != NULL; el = el->next) {
    if (el->val == val) {
      el->count += 1;

      if (el->count > this->max_->count) {
        this->max_ = el;
      }

      return;
    }
  }

  if(this->count_ > this->threshold_) {
    this->rehash();
    index = val % this->dim_;
  }

  this->table_[index] = new Node(val, 1, this->table_[index]);
  this->count_ += 1;

  if (this->table_[index]->count > this->max_->count) {
    this->max_ = this->table_[index];
  }
}

void HashTable::rehash() {
  int old_dim = this->dim_;
  int index;
  Node** old_table = this->table_;

  this->dim_ = 1 + (this->dim_ << 1);
  this->threshold_ = this->dim_ * 0.75;
  this->table_ = new Node*[this->dim_];
  this->reset_table();

  for (int i = 0; i < old_dim; ++i) {
    if (old_table[i] != NULL) {
      for (Node* el = old_table[i]; el != NULL; el = el->next) {
        index = el->val % this->dim_;
        this->table_[index] = new Node(el->val, el->count, this->table_[index]);
      }
    }
  }

  delete old_table;
}

HashTable::Node* HashTable::get_max() {
  return this->max_;
}

HashTable::Node* HashTable::operator[](const int& index) const {
  return this->table_[index];
}

void HashTable::reset_table() {
  for (int i = 0; i < this->dim_; ++i) {
    this->table_[i] = NULL;
  }
}

int main() {
  int n, a;
  HashTable ht;
  HashTable::Node* max;

  freopen("elmaj.in", "r", stdin);
  freopen("elmaj.out", "w", stdout);

  scanf("%d", &n);
  for (int i = 0; i < n; ++i) {
    scanf("%d", &a);
    ht << a;
  }

  max = ht.get_max();

  if (max->count >= 1 + (n >> 1)) {
    printf("%d %d\n", max->val, max->count);
  } else {
    printf("-1\n");
  }

  fcloseall();

  return 0;
}