数算!

This commit is contained in:
rogerwang2008 committed 2026-10-16 10:21:53 +08:00
1 parent ca6daa582c
commit e0c09e0c7b
22 files changed
+1344 -105

No files matched your search

@@ -0,0 +1,106 @@
#include <cassert>
#include <iostream>
#include <vector>
#include <algorithm>
#include <sstream>
class BinaryTree {
public:
struct Node {
int value = -1;
Node *father = nullptr, *left = nullptr, *right = nullptr;
};
Node* root = nullptr;
void reconstruct(const std::vector<int>& inorder_traversal, const std::vector<int>& postorder_traversal) {
assert(inorder_traversal.size() == postorder_traversal.size());
root = reconstruct_node(
inorder_traversal, postorder_traversal,
0, inorder_traversal.size(),
0, inorder_traversal.size());
}
[[nodiscard]] std::vector<int> preorder_traversal() {
std::vector<int> result;
preorder_dfs(root, result);
return result;
}
protected:
Node* reconstruct_node(
const std::vector<int>& inorder_traversal, const std::vector<int>& postorder_traversal,
std::size_t inorder_begin, std::size_t inorder_end, std::size_t postorder_begin, std::size_t postorder_end
) {
if (inorder_end - inorder_begin == 1) {
return new Node({.value = inorder_traversal[inorder_begin]});
}
if (inorder_end == inorder_begin) { return nullptr; }
auto in_begin = inorder_traversal.begin() + inorder_begin;
auto in_end = inorder_traversal.begin() + inorder_end;
auto root_idx = std::find(
in_begin, in_end,
postorder_traversal[postorder_end - 1]
) - inorder_traversal.begin();
auto left_length = root_idx - inorder_begin;
auto right_length = inorder_end - root_idx - 1;
Node* left_node = reconstruct_node(
inorder_traversal, postorder_traversal,
inorder_begin, root_idx, postorder_begin, postorder_begin + left_length
);
Node* right_node = reconstruct_node(
inorder_traversal, postorder_traversal,
root_idx + 1, inorder_end, postorder_end - 1 - right_length, postorder_end - 1
);
Node* node = new Node({
.value = inorder_traversal[root_idx],
.left = left_node, .right = right_node,
});
if (left_node != nullptr) { left_node->father = node; }
if (right_node != nullptr) { right_node->father = node; }
return node;
}
void preorder_dfs(Node* node, std::vector<int>& result) {
if (node == nullptr) { return; }
result.push_back(node->value);
preorder_dfs(node->left, result);
preorder_dfs(node->right, result);
}
};
std::ostream& operator<<(std::ostream& os, const std::vector<int>& vector) {
for (int x : vector) { os << x << ' '; }
return os;
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::vector<int> inorder_traversal, postorder_traversal;
std::string lines[2];
std::getline(std::cin, lines[0]);
std::getline(std::cin, lines[1]);
std::istringstream iss1(lines[0]), iss2(lines[1]);
int temp;
while (iss1 >> temp) {
inorder_traversal.push_back(temp);
}
while (iss2 >> temp) {
postorder_traversal.push_back(temp);
}
std::clog << inorder_traversal << std::endl << postorder_traversal << std::endl;
BinaryTree binary_tree;
binary_tree.reconstruct(inorder_traversal, postorder_traversal);
std::cout << binary_tree.preorder_traversal() << std::endl;
return 0;
}
@@ -0,0 +1,62 @@
#include <cmath>
#include <functional>
#include <iostream>
class BinaryTree {
public:
struct Node {
int value = -1;
Node *father = nullptr, *left = nullptr, *right = nullptr;
int depth = -1;
};
Node* root = new Node({.depth = 0});
void init_full_tree(int height, const std::function<bool(int, int)>& comp) {
int id = 0;
return init_full_tree(height, comp, 0, nullptr, id);
}
protected:
void init_full_tree(int height, const std::function<bool(int, int)>& comp,
int current_depth, Node* current_node, int& id) {
if (current_depth == 0) { current_node = root; }
if (current_depth == height) {
current_node->value = id++;
return;
}
current_node->left = new Node();
current_node->right = new Node();
init_full_tree(height, comp, current_depth + 1, current_node->left, id);
init_full_tree(height, comp, current_depth + 1, current_node->right, id);
if (comp(current_node->left->value, current_node->right->value)) {
current_node->value = current_node->right->value;
} else {
current_node->value = current_node->left->value;
}
}
};
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int n;
BinaryTree binary_tree;
std::vector<int> strengths;
std::cin >> n;
strengths.resize(static_cast<std::size_t>(std::pow(2, n)));
for (int& strength : strengths) { std::cin >> strength; }
binary_tree.init_full_tree(n,
[strengths](int i, int j) {
return strengths[i] < strengths[j];
});
// std::cout << binary_tree.root->value << std::endl;
int gold = binary_tree.root->value;
int silver = binary_tree.root->left->value == gold
? binary_tree.root->right->value
: binary_tree.root->left->value;
std::cout << silver + 1 << std::endl;
return 0;
}
@@ -0,0 +1,103 @@
#include <iostream>
#include <vector>
constexpr int MAX_N = 1e5 + 1;
class BinaryTree {
public:
using NodeIdx = int;
struct Node {
NodeIdx father = -1, left = -1, right = -1;
};
NodeIdx root = -1;
std::vector<Node> nodes;
explicit BinaryTree(int n) : nodes(n) {}
NodeIdx init_root() {
root = 0;
while (nodes[root].father != -1) {
root = nodes[root].father;
}
return root;
}
[[nodiscard]] std::vector<int> preorder_traversal() {
std::vector<int> result;
result.reserve(nodes.size());
preorder_dfs(root, result);
return result;
}
[[nodiscard]] std::vector<int> postorder_transversal() {
std::vector<int> result;
result.reserve(nodes.size());
postorder_dfs(root, result);
return result;
}
[[nodiscard]] std::vector<int> inorder_transversal() {
std::vector<int> result;
result.reserve(nodes.size());
inorder_dfs(root, result);
return result;
}
protected:
void preorder_dfs(NodeIdx node, std::vector<int>& result) {
if (node == -1) { return; }
result.push_back(node);
preorder_dfs(nodes[node].left, result);
preorder_dfs(nodes[node].right, result);
}
void postorder_dfs(NodeIdx node, std::vector<int>& result) {
if (node == -1) { return; }
postorder_dfs(nodes[node].left, result);
postorder_dfs(nodes[node].right, result);
result.push_back(node);
}
void inorder_dfs(NodeIdx node, std::vector<int>& result) {
if (node == -1) { return; }
inorder_dfs(nodes[node].left, result);
result.push_back(node);
inorder_dfs(nodes[node].right, result);
}
};
std::ostream& operator<<(std::ostream& os, const std::vector<int>& vector) {
for (int x : vector) { os << x + 1 << ' '; }
return os;
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int n;
std::cin >> n;
BinaryTree binary_tree(n);
for (int i = 0; i < n; i++) {
int x, y;
std::cin >> x >> y;
x--, y--;
binary_tree.nodes[i].left = x;
binary_tree.nodes[i].right = y;
if (x >= 0) { binary_tree.nodes[x].father = i; }
if (y >= 0) { binary_tree.nodes[y].father = i; }
}
binary_tree.init_root();
std::cout << binary_tree.preorder_traversal() << std::endl;
std::cout << binary_tree.inorder_transversal() << std::endl;
std::cout << binary_tree.postorder_transversal() << std::endl;
return 0;
}