All projects/ Pro Competitive ProgrammingALGORITHMS
C++ALGORITHMS / C++ / PROBLEM SOLVING

Pro Competitive
Programming.

835 problems. My solutions.
Shared to help others learn.

I turned my C++ practice into a public learning resource, with solutions, explanations, and tests for students preparing for competitions, coursework, and technical interviews.

ALGORITHM NOTEBOOK
Understand the pattern. Follow the implementation.
WHY I BUILT IT

My practice. A resource for other students.

I worked through 835 problems from CSES, Codeforces, and AtCoder to sharpen my C++ and algorithmic problem-solving skills. I published my solutions on GitHub with the reasoning behind each approach, time and space complexity, and tests for the edge cases. What began as my own practice is now an open resource for students preparing for competitions and technical interviews, strengthening their algorithms coursework, or becoming more confident C++ programmers.

Prepare with a purpose

Practice problems across graph algorithms, dynamic programming, greedy methods, strings, and number theory, organized so students can work on the topics they need.

Learn the reasoning

My notes explain why an approach works, what it costs, and where it can go wrong, helping students recognize the same idea in a new problem.

Run it. Test it. Build on it.

Every solution compiles on its own. Students can run the tests, explore edge cases, and study reusable data structures as they develop their own implementations.

Graph algorithmsDynamic programmingBinary searchRange queriesGreedy algorithmsStringsNumber theoryCombinatorics
IMPLEMENTATION & TESTING

C++ at the center.

C++17 solutions and reusable headers, with Python tooling for catalogue checks, test execution, and differential verification.

SEE THE REASONING

Six patterns, made visible.

These worked examples show the ideas behind my solutions. Follow a diagram, trace the steps, and connect the reasoning to the C++ implementation below.

Dijkstra worked example for Shortest Routes I
Dijkstra

Shortest Routes I

Start at city 1, always expand the cheapest unsettled route, and skip stale queue entries.

Explore the solution
Dynamic programming worked example for Frog 1
Dynamic programming

Frog 1

At each stone, compare the cost of jumping from one or two stones back.

Explore the solution
Fenwick tree worked example for Dynamic Range Sum Queries
Fenwick tree

Dynamic Range Sum Queries

Keep partial sums in a Fenwick tree; updates and prefix queries follow the lowest set bit.

Explore the solution
0/1 knapsack worked example for Book Shop
0/1 knapsack

Book Shop

Process budgets backwards so each book can contribute at most once.

Explore the solution
Binary search worked example for Factory Machines
Binary search

Factory Machines

Search for the first time at which the machines can produce the target quantity.

Explore the solution
Counting worked example for Same Differences
Counting

Same Differences

Rearrange a[j] − a[i] = j − i into equal values of a[i] − i, then count previous matches.

Explore the solution
READ THE C++

Inside my solutions.

Six examples from my collection, covering different ways to approach a problem. Read the C++ here, then open my notes for the reasoning, complexity, and mistakes to watch for.

CSES · 1671Dijkstra

Shortest Routes I

Start at city 1, always expand the cheapest unsettled route, and skip stale queue entries.

TIMEO((n + m) log(n + m))SPACEO(n + m)
Read C++17 implementation
// Shortest Routes I | https://cses.fi/problemset/task/1671/
// Time: O((n + m) log(n + m)); extra space: O(n + m).
#include <iostream>
#include <vector>
#include <queue>
#include <functional>
#include <utility>
#include <limits>



void solve() {
    int n, m;
    std::cin >> n >> m;
    std::vector<std::vector<std::pair<int, long long>>> graph(n);
    for (int i = 0; i < m; ++i) {
        int a, b;
        long long cost;
        std::cin >> a >> b >> cost;
        graph[a - 1].emplace_back(b - 1, cost);
    }
    constexpr long long infinity = std::numeric_limits<long long>::max() / 4;
    std::vector<long long> distance(n, infinity);
    using State = std::pair<long long, int>;
    std::priority_queue<State, std::vector<State>, std::greater<State>> queue;
    distance[0] = 0;
    queue.emplace(0, 0);
    while (!queue.empty()) {
        auto [cost, u] = queue.top(); queue.pop();
        if (cost != distance[u]) continue;
        for (auto [v, weight] : graph[u]) {
            if (cost + weight < distance[v]) {
                distance[v] = cost + weight;
                queue.emplace(distance[v], v);
            }
        }
    }
    for (int i = 0; i < n; ++i) std::cout << distance[i] << (i + 1 == n ? '\n' : ' ');
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    solve();
}
AtCoder · DP ADynamic programming

Frog 1

At each stone, compare the cost of jumping from one or two stones back.

TIMEO(n)SPACEO(n)
Read C++17 implementation
// Frog 1 | https://atcoder.jp/contests/dp/tasks/dp_a
// Time: O(n); extra space: O(n).
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <limits>



void solve() {
    int n; std::cin >> n;
    std::vector<long long> height(n), best(n, std::numeric_limits<long long>::max() / 4);
    for (auto& value : height) std::cin >> value;
    best[0] = 0;
    for (int i = 1; i < n; ++i) {
        best[i] = best[i - 1] + std::abs(height[i] - height[i - 1]);
        if (i >= 2) best[i] = std::min(best[i], best[i - 2] + std::abs(height[i] - height[i - 2]));
    }
    std::cout << best.back() << '\n';
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    solve();
}
CSES · 1648Fenwick tree

Dynamic Range Sum Queries

Keep partial sums in a Fenwick tree; updates and prefix queries follow the lowest set bit.

TIMEO(log n) per querySPACEO(n)
Read C++17 implementation
// Dynamic Range Sum Queries | https://cses.fi/problemset/task/1648/
// Time: O((n + q) log n); extra space: O(n).
#include <iostream>
#include <vector>



void solve() {
    int n, q;
    std::cin >> n >> q;
    std::vector<long long> values(n + 1), tree(n + 1);
    auto add = [&](int index, long long delta) {
        for (; index <= n; index += index & -index) tree[index] += delta;
    };
    auto prefix = [&](int index) {
        long long answer = 0;
        for (; index > 0; index -= index & -index) answer += tree[index];
        return answer;
    };
    for (int i = 1; i <= n; ++i) { std::cin >> values[i]; add(i, values[i]); }
    while (q--) {
        int type, a; long long b;
        std::cin >> type >> a >> b;
        if (type == 1) { add(a, b - values[a]); values[a] = b; }
        else std::cout << prefix(static_cast<int>(b)) - prefix(a - 1) << '\n';
    }
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    solve();
}
CSES · 11580/1 knapsack

Book Shop

Process budgets backwards so each book can contribute at most once.

TIMEO(n × budget)SPACEO(n + budget)
Read C++17 implementation
// Book Shop | https://cses.fi/problemset/task/1158/
// Time: O(n * x); extra space: O(n + x).
#include <iostream>
#include <vector>
#include <algorithm>



void solve() {
    int n, budget;
    std::cin >> n >> budget;
    std::vector<int> price(n), pages(n), best(budget + 1);
    for (auto& value : price) std::cin >> value;
    for (auto& value : pages) std::cin >> value;
    for (int book = 0; book < n; ++book) {
        for (int money = budget; money >= price[book]; --money) {
            best[money] = std::max(best[money], best[money - price[book]] + pages[book]);
        }
    }
    std::cout << best[budget] << '\n';
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    solve();
}
CSES · 1620Binary search

Factory Machines

Search for the first time at which the machines can produce the target quantity.

TIMEO(n log(min(k) × target))SPACEO(n)
Read C++17 implementation
// Factory Machines | https://cses.fi/problemset/task/1620/
// Time: O(n log(min(k) * t)); extra space: O(n).
#include <iostream>
#include <vector>
#include <algorithm>



void solve() {
    int n;
    long long target;
    std::cin >> n >> target;
    std::vector<long long> times(n);
    for (auto& time : times) std::cin >> time;
    long long low = 0;
    long long high = *std::min_element(times.begin(), times.end()) * target;
    auto enough = [&](long long duration) {
        long long made = 0;
        for (long long time : times) {
            long long produced = duration / time;
            if (produced >= target - made) return true;
            made += produced;
        }
        return false;
    };
    while (low < high) {
        long long middle = low + (high - low) / 2;
        if (enough(middle)) high = middle;
        else low = middle + 1;
    }
    std::cout << low << '\n';
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    solve();
}
Codeforces · 1520DCounting

Same Differences

Rearrange a[j] − a[i] = j − i into equal values of a[i] − i, then count previous matches.

TIMEO(n log n)SPACEO(n)
Read C++17 implementation
// Same Differences | https://codeforces.com/problemset/problem/1520/D
// Time: O(n log n) per case; extra space: O(n).
#include <iostream>
#include <map>



void solve() {
    int tests; std::cin >> tests;
    while (tests-- > 0) {
        int n; std::cin >> n; std::map<long long,long long> frequency; long long answer=0;
        for (int i=0;i<n;++i) { long long value; std::cin >> value; answer+=frequency[value-i]++; }
        std::cout << answer << '\n';
    }
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    solve();
}
RECORDED OCTOBER 7, 2026

Tested beyond the sample cases.

I include tests alongside the solutions so students can check their understanding and catch mistakes. These results are recorded in the repository from local runs on Linux with GCC 13.3.0 and Python 3.12.14.

835

Standalone C++17 builds

Warnings treated as errors.

2,964

Fixed input/output cases

Distinct sample and edge-case fixtures.

32,040

Library property comparisons

Reusable structures checked against simple models.

10,100

Differential & structural cases

101 solutions; deterministic seed 2110.

31

Constraint-limit regressions

Large inputs, long chains, and integer limits.

35

Runner & checker tests

Catalogue integrity and semantic output checks.

CHECK THE WORK YOURSELF

The verification notes include the commands, test coverage, and boundary cases behind these results. All 835 solutions were included in the recorded sanitizer and library-assertion checks. Students can reproduce the runs and add tests of their own.

KEEP EXPLORING

Use it in your own preparation.

I made the collection public so other students can learn from the work I put into it. Choose a topic, try a problem, and use my explanation to work through the parts that are still unclear. The repository also includes a learning roadmap, C++ notes, and reusable data structures.

Pro-Competitive-Programming public GitHub repository listing, supplied by Michael
The public repository. Counts and code on this page reflect the October 8, 2026 snapshot.