Cod sursa(job #2070796)

Utilizator Stefan_RaduStefan Radu Stefan_Radu Data 19 noiembrie 2017 22:16:00
Problema Coduri Huffman Scor 90
Compilator cpp Status done
Runda Arhiva educationala Marime 2.39 kb
#include <cstdio>
#include <vector>
#include <cctype>
   
using namespace std;

FILE *in, *out;
const int MAXBUFF = 4096;
char buff[MAXBUFF];
int index = MAXBUFF;

inline char next_char() {
  if (index == MAXBUFF) {
    fread(buff, 1, MAXBUFF, in);
    index = 0;
  }
  return buff[index ++];
}

inline int get_nr() {

  char chr = next_char();
  while (not isdigit(chr)) {
    chr = next_char();
  }

  int nr = 0;
  while (isdigit(chr)) {
    nr = nr * 10 + chr - '0';
    chr = next_char();
  }
  return nr;
}
   
struct node {
     
  node (long long val, int leaf) {
    for (auto &x : next_node) {
      x = NULL;
    }
    this -> val = val;
    this -> leaf_cnt = leaf;
  }
   
  int leaf_cnt;
  long long val;
  node* next_node[2];
};
   
inline void get_cur(vector < node* > &in_q, vector < node* > &sec_q, node* &cur_n,
  int &l1, int &r1, int &l2, int &r2) {
   
  if ((r1 - l1) and (r2 - l2)) {
    if (in_q[l1] -> val <= sec_q[l2] -> val) {
      cur_n = in_q[l1 ++];
    }
    else {
      cur_n = sec_q[l2 ++];
    }
  }
  else if (r1 - l1) {
    cur_n = in_q[l1 ++];
  }
  else {
    cur_n = sec_q[l2 ++];
  }  
}
  
inline void Dfs(long long bin, int len, node* cur_node,
  vector < pair < int, long long > > &ans) {
   
  if (cur_node -> leaf_cnt) {
    ans[cur_node -> leaf_cnt] = {len, bin};
    return;
  }
   
  Dfs(bin << 1, len + 1, cur_node -> next_node[0], ans);
  Dfs(bin << 1 | 1, len + 1, cur_node -> next_node[1], ans);
}
   
int main(int argc, char const *argv[]) {
     
  in = fopen("huffman.in", "r");
  out = fopen("huffman.out", "w");
  
  int n = get_nr();  
  node* cur = NULL;
  node* cur_left = NULL;
  node* cur_right = NULL;
  vector < node* > in_q(n + 2);
  vector < node* > sec_q(n + 2);
  vector < pair < int, long long > > ans(n + 1);
 
  for (int i = 1; i <= n; i ++) {
       
    int val = get_nr();
    in_q[i] = new node(1ll * val, i);
  }
  
  long long sum = 0;
  int l1 = 1, r1 = n + 1, l2 = 1, r2 = 1; 
  while (r1 + r2  - l1 - l2 > 1) {
   
    get_cur(in_q, sec_q, cur_left, l1, r1, l2, r2);
    get_cur(in_q, sec_q, cur_right, l1, r1, l2, r2);
   
    cur = new node(cur_left -> val + cur_right -> val, 0);
    cur -> next_node[0] = cur_left;
    cur -> next_node[1] = cur_right;
    sec_q[r2 ++] = cur;
    sum += cur -> val;
  }
   
  fprintf(out, "%lld\n", sum);
  Dfs(0, 0ll, cur, ans);
  for (int i = 1; i <= n; i ++) {
    fprintf(out, "%d %lld\n", ans[i].first, ans[i].second);
  }
}