DSA sheet / Sorting and searching

Stick Lengths

easy about 15 min mediansortinggreedy
Open on CSES

Do these first: Distinct Numbers

The problem in brief

You have n sticks (up to 200 000) with given lengths up to 10^9. Making a stick longer or shorter by d costs d. Print the minimum total cost to make every stick the same length.

Try it

Tab indents; press Esc, then Tab, to leave the box. Ctrl+Enter runs.

Hints

Stuck? Reveal one hint at a time. Each nudges without giving away the next.

The walkthrough

Spoilers ahead: open a section only after you have given the hints a fair try.

How to think

You are minimising f(L) = sum of |a_i - L| over all sticks. Each |a_i - L| is a V-shape, so f is a sum of V-shapes: piecewise linear and convex. The minimum is where the slope crosses zero. Moving L up by one costs one for every stick at or below L and saves one for every stick above it. As long as more sticks are above than below, raising L helps; the balance point is the median.

So the answer is: sort, take the middle element as L, add up the distances. A brute-force approach would try all L, which you can use in testing on tiny inputs to confirm the median claim, but is hopeless at 10^9. For an even count, any L between the two middle values is equally good, so either middle element works.

The habit: turn “make everything equal” into a one-variable cost function, spot convexity, and locate the optimum at a balance point, here the median (for squared costs it would be the mean).

Intuition

Picture the sticks as points on a line and one meeting place for all of them. To minimise total walking, pick the median: if you stand anywhere else, shifting toward the median moves more people closer than farther.

Approach
  1. Sort the lengths.
  2. Take L = a[n / 2] (integer division; any of the two middle elements works for even n).
  3. Sum |a_i - L| over all i and print it.

Pitfalls: total cost can reach 2 * 10^5 * 10^9 = 2 * 10^14 so use 64-bit. You do not need to test values other than the median.

Complexity

O(n log n) for the sort, O(n) for the sum; O(n) memory.

Solutions

Written from scratch and checked by compiling and running each one against a brute force on random inputs. Fast input/output, the way you would submit it.

Show solutions (C++17, Python 3, Java 17, Node.js)
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin >> n;
    vector<long long> a(n);
    for (auto &x : a) cin >> x;
    sort(a.begin(), a.end());
    long long mid = a[n / 2], cost = 0;
    for (long long x : a) cost += llabs(x - mid);
    cout << cost << "\n";
    return 0;
}

Problem: CSES Problem Set (Antti Laaksonen, University of Helsinki), CC BY-NC-SA 4.0. The explanations and code above are original (© Anupam Kumar).

Related problems

Back to the sheet