Cod sursa(job #3233219)

Utilizator MirceaDonciuLicentaLicenta Mircea Donciu MirceaDonciuLicenta Data 2 iunie 2024 19:59:59
Problema Coduri Huffman Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.1 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <string>
#include <unordered_map>

using namespace std;

struct Node {
    long long freq;
    char symbol;
    Node* left;
    Node* right;

    Node(long long f, char s = '\0', Node* l = nullptr, Node* r = nullptr)
        : freq(f), symbol(s), left(l), right(r) {}
};

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

void generateCodes(Node* root, string code, unordered_map<char, string>& huffmanCode) {
    if (root == nullptr)
        return;

    if (root->left == nullptr && root->right == nullptr) {
        huffmanCode[root->symbol] = code;
    }

    generateCodes(root->left, code + "0", huffmanCode);
    generateCodes(root->right, code + "1", huffmanCode);
}

int main() {
    ifstream infile("huffman.in");
    ofstream outfile("huffman.out");

    if (!infile || !outfile) {
        cerr << "Error opening file" << endl;
        return 1;
    }

    int n;
    infile >> n;

    vector<long long> freqs(n);
    for (int i = 0; i < n; ++i) {
        infile >> freqs[i];
    }

    priority_queue<Node*, vector<Node*>, compare> pq;

    for (int i = 0; i < n; ++i) {
        pq.push(new Node(freqs[i], i));
    }

    while (pq.size() != 1) {
        Node* left = pq.top(); pq.pop();
        Node* right = pq.top(); pq.pop();

        long long sum = left->freq + right->freq;
        pq.push(new Node(sum, '\0', left, right));
    }

    Node* root = pq.top();

    unordered_map<char, string> huffmanCode;
    generateCodes(root, "", huffmanCode);

    long long totalLength = 0;
    vector<pair<int, long long>> codes;
    for (int i = 0; i < n; ++i) {
        string code = huffmanCode[i];
        totalLength += freqs[i] * code.length();
        codes.push_back({code.length(), stoll(code, nullptr, 2)});
    }

    outfile << totalLength << endl;
    for (const auto& p : codes) {
        outfile << p.first << " " << p.second << endl;
    }

    infile.close();
    outfile.close();

    return 0;
}