Luogu Contest Solutions: Set Operations, Tree Traversal, and Expression Parsing
Problem 1: Finding the k-th Smallest Unique Integer
This problem demonstrates the efficient use of ordered sets for automatic deduplication and sorting. The key insight is leveraging std::set properties to eliminate duplicates while maintaining ascending order, then directly accessing the k-th element.
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int totalCount, targetRank;
cin >> totalCount >> targetRank;
set<int> uniqueNumbers;
for (int i = 0; i < totalCount; ++i) {
int value;
cin >> value;
uniqueNumbers.insert(value);
}
if (targetRank > static_cast<int>(uniqueNumbers.size())) {
cout << "NO RESULT" << '\n';
} else {
int currentPosition = 0;
for (int num : uniqueNumbers) {
++currentPosition;
if (currentPosition == targetRank) {
cout << num << '\n';
break;
}
}
}
return 0;
}
Problem 2: T-Shirt Distribution Strategy
After sorting the list of participant sizes, we need to determine the minimum number of people who will receive shirts. The solution involves identifying groups with identical sizes at the cutoff point by scanning backwards from the k-th position.
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int participantCount, minimumRecipients;
cin >> participantCount >> minimumRecipients;
vector<int> sizes(participantCount);
for (int &size : sizes) {
cin >> size;
}
sort(sizes.begin(), sizes.end());
int extraRecipients = 0;
int checkIndex = participantCount - minimumRecipients - 1;
while (checkIndex >= 0 && sizes[checkIndex] == sizes[checkIndex + 1]) {
++extraRecipients;
--checkIndex;
}
cout << minimumRecipients + extraRecipients << '\n';
return 0;
}
Problem 3: Simple Arithmetic Expression Evaluator
This solution parses and evaluates expressions containing only addition and subtraction. Since all terms are non-negative, we can process left-to-right without complex operator precedence. The algorithm tracks the current operator and accumulates values accordingly.
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
string expression;
cin >> expression;
int total = 0;
char currentOperator = '+';
size_t index = 0;
while (index < expression.length()) {
int termValue = 0;
while (index < expression.length() && isdigit(expression[index])) {
termValue = termValue * 10 + (expression[index] - '0');
++index;
}
if (currentOperator == '-') {
total -= termValue;
} else {
total += termValue;
}
if (index < expression.length()) {
currentOperator = expression[index];
++index;
}
}
cout << total << '\n';
return 0;
}
Problem 4: Expanded Base Representation
Convert a number string into its expanded polynomial form in the given base. The algorithm counts non-zero digits first, then outputs each term with proper exponent values, handling plus sign separators between terms.
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int base;
string numberStr;
cin >> base >> numberStr;
int nonZeroCount = 0;
for (char digit : numberStr) {
if (digit != '0') {
++nonZeroCount;
}
}
for (size_t pos = 0; pos < numberStr.length(); ++pos) {
char digit = numberStr[pos];
if (digit != '0') {
int exponent = numberStr.length() - pos - 1;
cout << digit << '*' << base << '^' << exponent;
--nonZeroCount;
if (nonZeroCount > 0) {
cout << '+';
}
}
}
return 0;
}
Problem 5: Binary Tree Traversal Implementation
Implementation of standard tree traversal algorithms (pre-order, in-order, post-order) for a binary tree stored using an array-based representation where nodes are indexed from 1 to n.
#include <bits/stdc++.h>
using namespace std;
const int MAX_NODES = 1000000;
struct TreeNode {
int parent;
int leftChild;
int rightChild;
};
vector<TreeNode> tree(MAX_NODES);
void preorderTraversal(int nodeId) {
if (nodeId == 0) return;
cout << nodeId << ' ';
preorderTraversal(tree[nodeId].leftChild);
preorderTraversal(tree[nodeId].rightChild);
}
void inorderTraversal(int nodeId) {
if (nodeId == 0) return;
inorderTraversal(tree[nodeId].leftChild);
cout << nodeId << ' ';
inorderTraversal(tree[nodeId].rightChild);
}
void postorderTraversal(int nodeId) {
if (nodeId == 0) return;
postorderTraversal(tree[nodeId].leftChild);
postorderTraversal(tree[nodeId].rightChild);
cout << nodeId << ' ';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int nodeCount;
cin >> nodeCount;
for (int i = 1; i <= nodeCount; ++i) {
int left, right;
cin >> left >> right;
tree[i].leftChild = left;
tree[i].rightChild = right;
if (left != 0) tree[left].parent = i;
if (right != 0) tree[right].parent = i;
}
preorderTraversal(1);
cout << '\n';
inorderTraversal(1);
cout << '\n';
postorderTraversal(1);
return 0;
}
Problem 6: Basic Addition with Large Numbers
A straightforward problem requiring 64-bit integers to prevent overflow. The solution reads two integers and outputs their sum, demonstrating proper type selection for competitive programming.
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int64_t firstValue, secondValue;
cin >> firstValue >> secondValue;
cout << firstValue + secondValue << '\n';
return 0;
}