A contest gives you the input SIZE before you write a line of code. "Fast enough?" means: will my plan finish inside the time limit at that size? This unit counts operations, compares growth rates, and reads constraints to CHOOSE an algorithm — then ships a fast stdin solver. Each idea is a short executable demo with a Notice.
-
Count the basic steps a plan takes as the input grows.
-
Tell the growth families
O(n),O(n squared)andO(log n)apart. -
Read the constraints and estimate whether a plan fits a budget of about 100,000,000 steps.
-
Replace a slow pair check with a one-pass dictionary solution.
-
Lesson 1 — Is My Plan Fast Enough?
Before writing a solution, count the work it does, see how that work grows with N, and check it against the contest's limits.
Count the Operations
The work a program does grows with the input. Count the basic steps for a single loop versus a nested loop over the same list.
values = [8, 3, 6, 1, 9] single_loop_checks = 0 for value in values: single_loop_checks = single_loop_checks + 1 print("N:", len(values)) print("Single-loop checks:", single_loop_checks) assert single_loop_checks == 5Scroll the code for more ↓
Output
N: 5 Single-loop checks: 5One loop over N items does N steps —
O(n).values = [8, 3, 6, 1, 9] nested_loop_checks = 0 for first in values: for second in values: nested_loop_checks = nested_loop_checks + 1 print("N:", len(values)) print("Nested-loop checks:", nested_loop_checks) assert nested_loop_checks == 25Scroll the code for more ↓
Output
N: 5 Nested-loop checks: 25A loop inside a loop does N×N steps —
O(n squared). Five items already cost 25.Three Growth Families
Picture how
O(n)andO(n squared)grow as N gets bigger (using multiplication, not powers).for n in [10, 100, 1000]: linear_work = n square_work = n * n print("N =", n, "O(n) picture =", linear_work, "O(n squared) picture =", square_work)Scroll the code for more ↓
Output
N = 10 O(n) picture = 10 O(n squared) picture = 100 N = 100 O(n) picture = 100 O(n squared) picture = 10000 N = 1000 O(n) picture = 1000 O(n squared) picture = 1000000At N=1000,
O(n)is 1000 butO(n squared)is 1,000,000 — a thousand times more work.Read the Constraints Before Choosing
Contests cap N. Estimate the cost ARITHMETICALLY (a multiplication, not a real loop) to see which plan fits a ~100,000,000-step budget.
small_n = 100 large_n = 100000 print("Small O(n squared) estimate:", small_n * small_n) print("Large O(n squared) estimate:", large_n * large_n) print("Large O(n) estimate:", large_n) assert small_n * small_n == 10000 assert large_n * large_n == 10000000000Scroll the code for more ↓
Output
Small O(n squared) estimate: 10000 Large O(n squared) estimate: 10000000000 Large O(n) estimate: 100000O(n squared)at N=100 is tiny (10,000) but at N=100,000 it is 10,000,000,000 — far over budget. The estimate is instant: no loop actually runs that many times.Halve a Number Range
When each step throws away half the possibilities, the count grows like
O(log n)— very slow growth.secret = 73 low = 1 high = 100 guesses = 0 while low <= high: guess = (low + high) // 2 guesses = guesses + 1 print("Guess", guesses, "tries", guess, "inside", low, "through", high) if guess == secret: break elif guess < secret: low = guess + 1 else: high = guess - 1 print("Found it in", guesses, "guesses") assert guess == 73 assert guesses == 6Scroll the code for more ↓
Output
Guess 1 tries 50 inside 1 through 100 Guess 2 tries 75 inside 51 through 100 Guess 3 tries 62 inside 51 through 74 Guess 4 tries 68 inside 63 through 74 Guess 5 tries 71 inside 69 through 74 Guess 6 tries 73 inside 72 through 74 Found it in 6 guesses1–100 is found in 6 guesses because each guess halves the range.
One Problem, Two Approaches
Two-sum: is there a pair adding to the target? The SLOW way checks every pair (
O(n squared)). Run it on a small literal input and count the checks.data = '6 20\n2 4 6 8 10 12' tokens = data.split() n = int(tokens[0]) target = int(tokens[1]) numbers = [] for position in range(n): numbers.append(int(tokens[position + 2])) checks = 0 found = False for first_position in range(n): for second_position in range(first_position + 1, n): checks = checks + 1 if numbers[first_position] + numbers[second_position] == target: found = True answer = "NO" if found: answer = "YES" print(answer + "\nPair checks: " + str(checks))Scroll the code for more ↓
Output
YES Pair checks: 156 numbers cost 15 pair checks. At N=100,000 that is about 5 billion — too slow. (Complexity is a judgement we make; it is not auto-checked by the tests.)
The FAST way remembers partners already seen in a dictionary and checks each number once (
O(n)).Put it together: the fast two-sum program reads
N, thetarget, then theNnumbers from stdin, and prints the answer plus how many partner checks it made.Try it import sys data = sys.stdin.read() tokens = data.split() n = int(tokens[0]) target = int(tokens[1]) seen = {} checks = 0 found = False for position in range(n): number = int(tokens[position + 2]) needed = target - number checks = checks + 1 if needed in seen: found = True seen[number] = True answer = "NO" if found: answer = "YES" print(answer + "\nPartner checks: " + str(checks))Scroll the code for more ↓
Run the full solver from this unit folder:
python assets/l1.py < assets/l1/1.inOne pass with a
seendictionary — each number does ONE partner check (6 here, versus 15 for the slow pair scan).Complexity:
O(n)— linear, versus the slowO(n squared)pair scan. At N=100,000 the fast solver does 100,000 checks, not 5 billion.A Contest Checklist
Before coding: (1) read the constraints; (2) estimate your plan's steps (N, N×N, N×log N); (3) compare to a ~100,000,000 budget; (4) if it is over, look for a faster idea (sorting, a dictionary, binary search). Fast enough beats clever.
-
One loop over N items is
O(n); a loop inside a loop isO(n squared). -
At N = 100,000, an
O(n squared)plan costs about 10,000,000,000 steps, far over budget. -
Halving a range each step takes only
O(log n)steps, so 1 to 100 needs just a few guesses. -
A
seendictionary finds a pair with a given sum in one pass instead of checking every pair. -
Check the constraints before coding: fast enough beats clever.
-
You can now estimate whether a plan is fast enough before you write it.