Cod sursa(job #3294484)

Utilizator obsidianMidnight Majesty obsidian Data 24 aprilie 2025 15:04:38
Problema Coduri Huffman Scor 65
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.37 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("huffman.in");
ofstream fout("huffman.out");
#define MAX_N 1000000

struct Node
{
    int idx;
    long freq;
    Node *left;
    Node *right;

    Node(int idx, long freq)
        : idx(idx), freq(freq), left(nullptr), right(nullptr)
    {
    }
    Node(int idx, long freq, Node *left, Node *right)
        : idx(idx), freq(freq), left(left), right(right)
    {
    }
};

struct NodeComparator
{
    bool operator()(Node *l, Node *r)
    {
        return l->freq > r->freq;
    }
};

struct HuffmanTree
{
    Node *root;
    priority_queue<Node *, vector<Node *>, NodeComparator> heap;

    HuffmanTree() : root(nullptr) {}

    void appendLeafNode(int idx, long freq)
    {
        Node *node = new Node(idx, freq);
        heap.push(node);
    }

    void build()
    {
        while (heap.size() != 1)
        {
            Node *left = heap.top();
            heap.pop();
            Node *right = heap.top();
            heap.pop();
            int sum = left->freq + right->freq;
            Node *node = new Node(-1, sum, left, right);
            heap.push(node);
        }
        root = heap.top();
        heap.pop();
    }

    void encode(Node *node, unordered_map<int, string> &encodings, string code)
    {
        if (node->left == nullptr && node->right == nullptr)
        {
            encodings[node->idx] = code;
            return;
        }
        encode(node->left, encodings, code + "0");
        encode(node->right, encodings, code + "1");
    }
};

long bin2Dec(string code)
{
    long res = 0L;
    for (int i = code.length() - 1; i >= 0; --i)
    {
        int pos = code.length() - i - 1;
        res |= (code[i] - '0') << pos ;
    }
    return res;
}

int main()
{
    long n, f;
    long freq[MAX_N];
    fin >> n;
    HuffmanTree tree;
    for (int i = 0; i < n; ++i)
    {
        fin >> freq[i];
        tree.appendLeafNode(i, freq[i]);
    }
    tree.build();

    unordered_map<int, string> encodings;
    tree.encode(tree.root, encodings, "");

    long sum = 0;
    for (int i = 0; i < n; ++i)
    {
        sum += freq[i] * encodings[i].length();
    }
    fout << sum << "\n";
    for (int i = 0; i < n; ++i)
    {
        fout << encodings[i].length() << " " << bin2Dec(encodings[i]) << "\n";
    }
    return 0;
}