Constructive problems ask you to build an object, or report that none exists. The difficulty is almost never the code. It’s finding the obstruction (an invariant) and a construction that works whenever the obstruction is absent.

Method

  1. Necessary conditions: parity, counts, sums, degree bounds, an invariant (Invariants).
  2. Brute force and print the solutions. Which inputs are solvable? What do the solutions look like?
  3. Guess a sufficient construction. Usually induction (extend or ), divide and conquer (solve halves, glue), or a closed-form pattern.
  4. Handle the small exceptions separately. Most constructions have two or three.
  5. Verify with a checker on all small inputs before submitting. Constructions are easy to get almost right.
  6. If direct construction doesn’t click, try visualising it by hand, modeling it as a graph, or working backwards/by complement/by symmetry — see Attacking a Problem for the general reformulation toolkit. If an attempt fails, pin down exactly why (counterexample, a violated invariant, an unjustified assumption) before trying the next idea.

Greedy constructions need a feasibility oracle: when you commit to the next piece, prove the rest is still completable. For the lexicographically smallest witness, try candidates in order and keep the first one whose residual instance passes the oracle. The oracle may be a counting inequality, a matching check (Hall), or a DP.

Recipes

RecipeExample
alternate extremes maximises adjacent gaps and makes adjacent differences distinct
pair with constant pair sums, symmetric arrangements
induction by 2 or 4extend a solution for to with a fixed gadget, plus base cases
recursive halvesGray code, Hanoi, L-tromino tilings, sorting networks

The binary-reflected Gray code is the cleanest instance: prefix to the -bit code and to its reversal. Adjacent codes within each half differ in one bit by induction, and the join (last code of the -half to first code of the reversed -half) differs in exactly the new top bit, since reversal makes that boundary pair identical on the low bits.
| powers of two | make subset sums or XORs independent; use bits to encode choices |
| linear patterns | , |
| colour or split by residue | odd and even positions, mod |
| most constrained first | biggest degree, largest value, fewest options |
| build the tree / skeleton first | then add extra edges or elements to adjust a count |
| fix the answer’s structure | “WLOG the answer has the form ”, then solve for parameters |
| interactive / adaptive | maintain a candidate set and halve it each step |

Permutations

GoalConstruction
exactly distinct values of (zigzag inward), then the remaining values in increasing order
derangementcyclic shift ; for “far from identity” use cyclically
adjacent elements differ by evens then odds (e.g. ); impossible for
pairwise distinct mod (0-indexed)identity works iff odd; for even it’s impossible since
all prefix sums distinct mod for even ; impossible for odd (proof below)
all prefix products distinct mod (permutation of ) via inverses mod prime ; exists only for prime, , or
exactly inversionsplace values from largest down; value placed with smaller ones after it adds inversions (treat position and value as separate coordinate systems — a swap can move the wrong statistic if you conflate them)
maximum reverse ()
given LIS length and LDS length exists iff (proof below); concatenate decreasing blocks of size
exists iff (proof below); 4-cycles
with (square root)pair cycles of equal even length; odd cycles have their own roots

Tested: all three existence criteria checked by brute force over all permutations of for small (up to 9-10), confirming the stated existence conditions match exhaustive search exactly.

Grids and matrices

GoalConstruction
Latin square
orthogonal Latin squares, odd and
odd magic squareSiamese method: start top middle, move up-right, drop down on collision
no two adjacent cells equalchessboard colouring, or
knight’s tour / Hamiltonian path on gridWarnsdorff heuristic (always move to the cell with fewest onward moves), or snake patterns for king/rook moves
every row and column sum odd/evenfix the first , solve the last row and column; consistent iff total parities agree
covering a grid with paths or cyclessnake (boustrophedon) order

Sequences and numbers

GoalConstruction
all subset sums distinct
distinct positives with sum , then (needs it )
no 3-term arithmetic progressionnumbers whose base-3 digits avoid 2 (greedy Stanley sequence)
pairwise coprimedistinct primes; consecutive integers; Fermat numbers
gcd exactly for every pair with distinct primes
overall but not pairwise coprimee.g. : , , , yet — “collectively coprime” is strictly weaker than pairwise coprime
(XOR is addition without carries)
numbers with XOR any distinct numbers, then their XOR (fix collisions with a high bit)
duplicate an element to cancel it; the basis of many “pair up and cancel” constructions
consecutive pair XORs to build a target XOR value out of such pairs when only “rotate the low bit” moves are allowed
XOR of for (proof below); blocks cancel
prescribed remaindersCRT — but check compatibility first when moduli aren’t pairwise coprime: and have a common solution iff , not automatically
represent as a sum of few special numbersLagrange (4 squares), Legendre (3 squares unless ), Goldbach-style searches for primes in practice, Zeckendorf for Fibonacci numbers

Graphs

GoalConstruction
connected with exactly edgesany spanning tree, then unused edges ()
realise a degree sequenceErdős-Gallai condition, then Havel-Hakimi (repeatedly connect the largest-degree vertex to the next largest)

Even degree sum is necessary, not sufficient

has an even sum () and every term , yet no simple graph on 4 vertices realises it: the two degree-3 vertices would each need to connect to all 3 others, forcing both degree-1 vertices up to degree 2. The full Erdős-Gallai condition (a prefix inequality for every ) is what’s actually necessary and sufficient — checking only the sum and the max term is not enough.
| bipartite degree sequences | Gale-Ryser, then greedy |
| tree with given degrees | any degree sequence of positive integers summing to ; build with a Prüfer-like greedy (leaf to smallest non-leaf) |
| diameter exactly | a path of length with the rest attached near the middle |
| -regular graph | circulant: (plus for odd , even ) |
| triangle-free with most edges | ; generally the Turán graph |
| exactly shortest paths, or spanning trees, etc. | binary encoding: a chain of “diamond” gadgets, one per bit of |
| graph with chromatic number and no triangle | Mycielski construction |
| tournament where each vertex beats exactly | for odd |
| orient edges so in/out degrees differ by | Euler tour after pairing odd-degree vertices with a dummy |

Binary-encoding gadgets are the standard trick for “construct a graph or grid with exactly of something” with small size: build a structure that doubles a count per layer, plus optional “+1” connections for the set bits of .

Always verify

Write a checker and run it on every up to 8-10 and on random inputs. Check boundary sizes and the impossible cases explicitly.

Construction methods in depth

A constructive problem asks for any object with given properties (or “-1”). The work is finding a family of objects you can describe in one line and prove correct. The overview with short recipes is Constructive Algorithms; this chapter goes deeper by object type.

Methods

MethodHow it goesTypical use
brute force, then patternenumerate all objects for , print the valid ones, look for a regular familypermutations, small grids
necessary conditions firstprove what any answer must satisfy (counts, parity, sums, bounds); then build an object meeting exactly those conditions”-1 or construct” problems
induction or extend an answer for a smaller by a gadget at the end; handle the base cases by handpermutations, graphs, tilings
extremes firstplace the largest / most constrained element first, where it hurts leastpermutations with conditions on neighbours
split into independent partsparity classes, residues, bits, connected componentsswaps at distance , bitwise conditions
greedy with a feasibility testbuild left to right; at each step take the smallest choice that keeps the rest feasiblelexicographically smallest answers
randomizationrandom object plus verification; repeatcolourings, hash-like objects, output-only tasks

Always ship a checker

Write the checker before the construction: it verifies the object against the statement in the most naive way. Run the construction for every small and every parameter, and compare “construction says impossible” with “brute force finds nothing”. All the code in this chapter was tested this way.

Example: all adjacent differences distinct

Find a permutation of whose adjacent differences are pairwise distinct. Alternate between the smallest and the largest unused value:

vector<int> distinctDiffPerm(int n) {          // |p[i+1] - p[i]| are n-1, n-2, ..., 1
    vector<int> p; int lo = 1, hi = n;
    for (int i = 0; i < n; i++) p.push_back(i % 2 == 0 ? lo++ : hi--);
    return p;
}

Related: Observation Toolkit.