Hackerrank Luck Balance solution in C++
The algorithm should be:


Lose any unimportant contest where doing so does not lose luck.
Win any contest where doing so does not lose luck.
Lose the up to k contests where winning would cost most luck.


At the moment, you assume winning never gains luck and losing never loses luck.

You do a full sort each iteration for point 3, which with a cost of \$O(k*\log(k))\$ leads to \$O(n*k*\log(k))\$.
Using a fixed-length priority-queue instead only needs \$O(\log(k))\$ per insert / replace, resulting in \$O(n*\log(k))\$, a factor of \$k\$ better.
While C++ doesn't have exactly that, &lt;algorithm&gt; provides pop_heap() and push_heap() which is enough to replace the head if the new item is less expensive. A custom replace_heap() or exposed down_heap() would be slightly more efficient, but for that you have to branch out.

Now the form:


&lt;bits/stdc++.h&gt; is non-standard and likely far more than you actually need. Unless coupled with use of precompiled headers, it will slow down compilation at least, if not bloat the resulting executable. Replace it with the standard includes. See "How does #include &lt;bits/stdc++.h> work in C++?".
Never import wholesale any namespace which isn't designed for it. Doing so leads to conflicts, silent changes of behaviour, and generally brittle code. See "Why is “using namespace std” considered bad practice?".
Don't use a std::vector if all you need is an array of statically-known length.
Such overkill costs. Anyway, a std::tuple&lt;int, bool&gt; or std::pair&lt;int, bool&gt; would be an even better fit.
If one can rely on anything, it's that if there is a way to screw something up, it will be done, at the most inconvenient time. Like the input. As it is under the coders control, it isn't quite a fatal defect though.
return 0; is implicit for main().
Small trivial types like char should not be passed by constant reference without good reason, but by value. Doing so avoids the pitfalls of aliasing, and is slightly more efficient. Happily, the compiler should fix that by inlining.
Getting and storing input in the loop-condition is actually idiomatic. And it avoids error-prone repetition.
This:

size_t i = 0;
size_t pos = input_string.find(delimiter);

while (pos != string::npos) {
    splits.push_back(input_string.substr(i, pos - i));

    i = pos + 1;
    pos = input_string.find(delimiter, i);
}


Could simply be:

for (size_t i = 0, pos; (pos = input_string.find(delimiter, i)) != string::npos; i = pos + 1)
    splits.push_back(input_string.substr(i, pos - i));

The final call to .substr() needlessly contains a complicated calculation for the second argument. Just leaving it out will do the right thing.

splits.push_back(input_string.substr(i, min(pos, input_string.length()) - i + 1));

As an aside, split_string() would be better off accepting a std::string_view and returning a std::vector&lt;std::string_view&gt;. Less allocation-overhead.
There is no reason to pass the contests by copy. Either move them, pass a constant reference, or preferably use a std::span (C++20 or GSL (Guideline Support Library)).
Yes, there's no need to forward-declare functions defined before first use, which is a good thing. But above all, please try to be consistent which option you use.


Finally your code:


There's no reason at all to keep track of parts of the result-sum separately. Just combine them already.
Using auto instead of explicit types avoids errors and reduces clutter. Thus, almost always auto. That also counts for the form.


The rest was handled in the algorithm section.

Using the better algorithm:

int luckBalance(int k, vector&lt;vector&lt;int&gt;&gt; contests) {
    // Keeping the bad interface because they force it
    auto r = 0;
    const auto heap = std::make_unique&lt;int[]&gt;(k);
    for (const auto&amp; x : contests) {
        if (!x[1] || x[0] &lt;= heap[0]) {
            r += std::abs(x[0]);
        } else {
            std::pop_heap(heap.get(), heap.get() + k, std::greater());
            r -= heap[k - 1];
            heap[k - 1] = x[0];
            std::push_heap(heap.get(), heap.get() + k, std::greater());
        }
    }
    return r;
}


Could be improved by not pre-filling the heap with zeroes, but I'm too lazy.