开始计概A下半学期。

This commit is contained in:
rogerwang2008 committed 2026-11-09 21:13:09 +08:00
1 parent 0cfdc8499c
commit 38e97654e1
31 files changed
+2144 -110

No files matched your search

@@ -0,0 +1,112 @@
#include <functional>
#include <iostream>
#include <optional>
#include <queue>
#include <unordered_map>
#include <utility>
class HuffmanTree {
public:
struct Node {
long long weight;
std::optional<std::string> content;
Node *left = nullptr, *right = nullptr;
bool operator<(const Node& other) const {
return weight < other.weight;
}
};
enum class DfsEntries { Pre, In, Post };
Node* root = nullptr;
explicit HuffmanTree(const std::unordered_map<std::string, long long>& freq_map) {
std::priority_queue<Node*, std::vector<Node*>,
std::function<bool(Node*, Node*)>>
nodes_heap([](Node* a, Node* b) { return a->weight > b->weight; });
for (const auto& [key, freq] : freq_map) {
nodes_heap.push(new Node{.weight = freq, .content = key});
}
while (nodes_heap.size() > 1) {
Node* node1 = nodes_heap.top();
nodes_heap.pop();
Node* node2 = nodes_heap.top();
nodes_heap.pop();
Node* new_node = new Node{.weight = node1->weight + node2->weight, .left = node1, .right = node2};
nodes_heap.push(new_node);
}
root = nodes_heap.top();
}
std::unordered_map<std::string, std::vector<bool>> get_encodings() {
std::unordered_map<std::string, std::vector<bool>> encodings;
if (root->left == nullptr && root->right == nullptr) {
encodings[root->content.value()] = {false};
} else {
dfs_with_path([&encodings](Node* node, std::vector<bool> path) {
if (!node->content.has_value()) { return; }
encodings[node->content.value()] = std::move(path);
});
}
return encodings;
}
protected:
void dfs_with_path(const std::function<void(Node*, std::vector<bool>)>& func,
DfsEntries func_entry = DfsEntries::Pre) {
std::vector<bool> path;
dfs_with_path(func, func_entry, path);
}
void dfs_with_path(const std::function<void(Node*, std::vector<bool>)>& func,
DfsEntries func_entry,
std::vector<bool>& path,
Node* node = nullptr) {
if (node == nullptr) { node = root; }
if (func_entry == DfsEntries::Pre) { func(node, path); }
if (node->left != nullptr) {
path.push_back(false);
dfs_with_path(func, func_entry, path, node->left);
path.pop_back();
}
if (func_entry == DfsEntries::In) { func(node, path); }
if (node->right != nullptr) {
path.push_back(true);
dfs_with_path(func, func_entry, path, node->right);
path.pop_back();
}
if (func_entry == DfsEntries::Post) { func(node, path); }
}
};
std::ostream& operator<<(std::ostream& os, const std::vector<bool>& bintree_path) {
for (const auto bin : bintree_path) {
os << (bin ? 1 : 0);
}
return os;
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int n;
std::cin >> n;
std::vector<std::string> keys(n);
std::unordered_map<std::string, long long> freq_map;
for (int i = 0; i < n; i++) {
int freq;
std::cin >> keys[i] >> freq;
freq_map[keys[i]] = freq;
}
HuffmanTree huffman_tree(freq_map);
auto encodings = huffman_tree.get_encodings();
for (const auto& key : keys) {
std::cout << key << ' ' << encodings[key] << std::endl;
}
return 0;
}