Fading Coder

One Final Commit for the Last Sprint

Home > Notes > Content

Luogu Contest Solutions: Set Operations, Tree Traversal, and Expression Parsing

Notes May 18 2

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;
}

Related Articles

Designing Alertmanager Templates for Prometheus Notifications

How to craft Alertmanager templates to format alert messages, improving clarity and presentation. Alertmanager uses Go’s text/template engine with additional helper functions. Alerting rules referenc...

Deploying a Maven Web Application to Tomcat 9 Using the Tomcat Manager

Tomcat 9 does not provide a dedicated Maven plugin. The Tomcat Manager interface, however, is backward-compatible, so the Tomcat 7 Maven Plugin can be used to deploy to Tomcat 9. This guide shows two...

Skipping Errors in MySQL Asynchronous Replication

When a replica halts because the SQL thread encounters an error, you can resume replication by skipping the problematic event(s). Two common approaches are available. Methods to Skip Errors 1) Skip a...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.