Appearance
Codeforces Tips and Workflow
A meta-guide covering contest strategy, testing workflow, and the mental game -- everything outside raw algorithmic knowledge that separates a 1100 from a 2100.
Prerequisites:
- Beginner-safe sections (any level): pre-contest checklist, testing workflow, sample tracing, common rating-specific mistakes.
- Full mental-game sections: a working C++20 setup and at least 10 rated contests under your belt — otherwise the pacing tables and tilt diagnostics will not map to your experience.
Quick Revisit
- Contest strategy, testing workflow, and mental game.
- Pre-contest checklist + stress-test scaffold are reusable from your first contest.
- Pacing tables, tilt management, and rating-band roadmaps assume you have ~10 rated contests of context.
Contents
- Contest Strategy
- Pre-Contest Checklist
- During Contest
- Testing Workflow
- Common Rating-Specific Mistakes
- Post-Contest
- Mental Game
- Useful CF Features
- Quick Reference: The 1100-to-2100 Roadmap
- What the Code Won't Teach You
- Self-Test
- Further Reading
Contest Strategy
Time Allocation
A typical Div 2 has 5 problems over 2 hours (120 min). A reasonable baseline pacing:
Problem Target Time Cumulative Expected Diff
------- ----------- ---------- -------------
A 5-8 min 8 min 800-1000
B 10-15 min 23 min 1000-1200
C 20-30 min 53 min 1300-1600
D 30-40 min 93 min 1600-1900
E 25-30 min 120 min 2000-2400This is a baseline, not a law. Some Div 2 rounds invert the curve (B harder than C, or a problem-D-shaped C). The habit that matters is tracking time and making deliberate skip decisions, not matching exact minute targets. If A takes more than 10 minutes, the signal is "re-read the statement," not "you are behind schedule."
When to Skip
- You have read the problem twice and have zero ideas after 5 minutes of thinking -- move on.
- You have a solution but it requires a data structure you have never implemented -- skip unless it is your last hope.
- You are debugging for 15+ minutes with no progress -- freeze, read the next problem, come back later.
When to Re-Read
Always re-read the problem statement when:
- Your sample output does not match.
- You get WA on pretest 2 or 3 (usually a misunderstood constraint).
- The problem "feels too easy" for its position -- you probably missed a condition.
Penalty Management
Penalty = time of accepted submission + 10 min per rejected submission on that problem. The math:
- Submitting a wrong answer at minute 20, then correct at minute 30 = penalty 40.
- Submitting correct at minute 35 with no wrong answers = penalty 35.
Rule of thumb: One careful submission at minute 35 beats a rushed one at minute 20 that gets WA. Do not submit until you have tested all samples and at least one edge case.
Pre-Contest Checklist
Run through this 5 minutes before the round starts.
1. Template File Ready
cpp
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int,int>;
#define all(v) (v).begin(), (v).end()
#define sz(v) (int)(v).size()
void solve() {
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t; cin >> t;
while (t--) solve();
}2. Compilation Command
bash
g++ -std=c++20 -O2 -Wall -Wextra -Wshadow -DLOCAL -o sol sol.cppFlags explained:
| Flag | Purpose |
|---|---|
-std=c++20 | Enable C++20 features (ranges, concepts, __lg) |
-O2 | Optimization -- catches some TLE-causing code patterns |
-Wall -Wextra | Warn on common mistakes (unused vars, sign compare) |
-Wshadow | Catch variable shadowing -- a silent killer |
-DLOCAL | Guard debug output behind #ifdef LOCAL |
3. Debug Macro
cpp
#ifdef LOCAL
#define dbg(x) cerr << #x << " = " << (x) << '\n'
#else
#define dbg(x)
#endif4. Environment
- Editor open, split pane with terminal.
- Browser on Codeforces contest page, logged in.
- No other tabs. Distractions are rating points left on the table.
During Contest
Read-First vs Dive-In
Two schools:
Strategy A: "Scan All" Strategy B: "Dive In"
+-------------------------+ +-------------------------+
| Read A,B,C,D,E (8 min) | | Read A -> Solve A |
| Rank by confidence | | Read B -> Solve B |
| Solve in order of ease | | Read C -> Solve C |
+-------------------------+ | ... |
+-------------------------+Recommendation: At 1100, use Strategy B. Problems A-C are almost always in order of difficulty. You do not yet have the speed-reading skill to benefit from scanning. Switch to Strategy A around 1600+ when D and E start having variable difficulty.
Estimating Difficulty
Look at the scoreboard after 15 minutes:
- If 3000+ people solved A but only 500 solved B, B is harder than usual -- budget more time.
- If C has more solves than B, consider doing C first.
Handling Wrong Answers
When you get WA:
WA on pretest 2-3 --> Re-read problem statement
|
v
WA on pretest 5+ --> Edge case: n=1, all same, max values
|
v
WA on pretest 10+ --> Overflow? Array bounds? Off-by-one?
|
v
Still WA --> Stress test (see below)Do NOT randomly tweak code. Every change should be motivated by a specific hypothesis.
Testing Workflow
This is the single biggest unlock between 1100 and 2100. Most 1100-rated players never stress test. Most 2100-rated players do it reflexively.
The Stress Testing Loop
+----------+ +----------+ +-----------+
| gen.cpp | ---> | sol.cpp | ---> | compare |
| (random | | (your | | output |
| input) | | solution)| | with |
+----------+ +----------+ | brute.cpp |
+-----------+
|
mismatch? --> print input, stopRandom Input Generator
cpp
#include <bits/stdc++.h>
using namespace std;
int main(int argc, char* argv[]) {
mt19937 rng(atoi(argv[1]));
auto randint = [&](int lo, int hi) {
return uniform_int_distribution<int>(lo, hi)(rng);
};
// Example: generate a single test case
// Adjust these ranges to match the problem constraints (use SMALL values)
int n = randint(1, 10);
cout << n << '\n';
for (int i = 0; i < n; i++) {
cout << randint(1, 100) << " \n"[i == n - 1];
}
}Key: the seed comes from argv[1] so each invocation produces different input.
Brute Force Solution
Write the dumbest correct solution you can.
cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n; cin >> n;
vector<int> a(n);
for (auto& x : a) cin >> x;
// brute force logic here -- clarity over speed
// ...
}The Stress Script
bash
#!/bin/bash
g++ -std=c++20 -O2 -o sol sol.cpp
g++ -std=c++20 -O2 -o brute brute.cpp
g++ -std=c++20 -O2 -o gen gen.cpp
for ((i = 1; i <= 1000; i++)); do
./gen $i > input.txt
./sol < input.txt > out1.txt
./brute < input.txt > out2.txt
if ! diff -q out1.txt out2.txt > /dev/null 2>&1; then
echo "MISMATCH on seed $i"
echo "--- Input ---"
cat input.txt
echo "--- Your output ---"
cat out1.txt
echo "--- Expected ---"
cat out2.txt
exit 1
fi
done
echo "OK: 1000 tests passed"Save this as stress.sh and run with bash stress.sh. When it finds a mismatch, you get the exact failing input. Debug from there.
STRESS TEST TIMELINE -- when to start:
Contest ----------------------------------->
0 min 120 min
| |
| Pre-built template (gen/brute/stress.sh) |
| ready BEFORE contest starts |
| | |
| +-- Problem A: no stress needed (easy) |
| +-- Problem B: stress if WA on pretest |
| +-- Problem C: stress BEFORE submitting |
| +-- Problem D: stress is mandatory |
| |
| Rule: for problems C+, set up stress FIRST, |
| then think about the algorithm. |
+-----------------------------------------------+Generating Specific Structures
Random tree (n nodes):
cpp
int n = randint(2, 10);
cout << n << '\n';
for (int i = 2; i <= n; i++) {
int parent = randint(1, i - 1);
cout << parent << ' ' << i << '\n';
}Random permutation:
cpp
int n = randint(1, 8);
vector<int> p(n);
iota(p.begin(), p.end(), 1);
shuffle(p.begin(), p.end(), rng);
cout << n << '\n';
for (int i = 0; i < n; i++) cout << p[i] << " \n"[i == n - 1];Random connected graph (n nodes, m edges):
cpp
int n = randint(2, 8);
int m = randint(n - 1, min(n * (n - 1) / 2, n + 5));
cout << n << ' ' << m << '\n';
// first a spanning tree
vector<int> perm(n);
iota(perm.begin(), perm.end(), 1);
shuffle(perm.begin(), perm.end(), rng);
set<pii> edges;
for (int i = 1; i < n; i++) {
int u = perm[randint(0, i - 1)], v = perm[i];
if (u > v) swap(u, v);
edges.insert({u, v});
cout << u << ' ' << v << '\n';
}
// then random extra edges
while (sz(edges) < m) {
int u = randint(1, n), v = randint(1, n);
if (u == v) continue;
if (u > v) swap(u, v);
if (edges.count({u, v})) continue;
edges.insert({u, v});
cout << u << ' ' << v << '\n';
}Common Rating-Specific Mistakes
What specifically trips up 1100-rated players, and how to fix it.
1. Not Reading the Full Problem
At 1100 you will lose more points to misreading than to not knowing algorithms. Read every word. Read the output format. Read the constraints -- they tell you the expected complexity.
Constraint-to-complexity cheat sheet:
n <= 10 --> O(n!) or O(2^n * n) brute force / bitmask
n <= 20 --> O(2^n) bitmask DP
n <= 500 --> O(n^3) Floyd, interval DP
n <= 5000 --> O(n^2) simple DP, brute-ish
n <= 3*10^5 --> O(n log n) sorting, segtree, BIT
n <= 10^6 --> O(n) linear scan, two pointers
n <= 10^9 --> O(log n) or O(sqrt(n)) binary search, math
n <= 10^18 --> O(log n) binary exp, math2. Integer Overflow
If int. Use ll (long long) for any multiplication of large values.
Danger pattern:
cpp
int a = 200000, b = 1000000000;
int result = a * b; // OVERFLOW -- undefined behavior3. Forgetting Edge Cases
Always test:
(single element) if allowed - All elements equal
- Already sorted / reverse sorted
- Maximum constraint values
4. Overcomplicating
If your solution for a Div 2 A or B exceeds 30 lines, you are probably overcomplicating it. Step back. Is there a simpler observation?
5. Copy-Paste Bugs
Solving multiple test cases? Make sure you clear your data structures between cases. The classic:
cpp
void solve() {
int n; cin >> n;
// WRONG: declared outside solve(), accumulates across test cases
// RIGHT: declared inside solve(), fresh each time
vector<int> a(n);
// ...
}6. Off-by-One in Binary Search
Use the template. Do not reinvent binary search each time. See Binary Search.
Post-Contest
Upsolving Strategy
Upsolving (solving problems you could not solve during the contest) is where the real learning happens.
Contest ends
|
v
Solve the next unsolved problem without reading editorial
(spend 30-60 min)
|
v
Still stuck? Read editorial for HINTS only, not full solution
|
v
Still stuck? Read full editorial, implement yourself
|
v
Implement, get AC, then read other people's solutions
|
v
Add the technique to your notesRule: Never read an editorial and say "oh I see" without implementing it. Understanding and implementing are different skills.
Virtual Contests
Codeforces -> Contests -> Virtual participation
Run past contests under real time pressure. This is the closest thing to a real contest without rating risk. Do at least 2 virtual contests per week if you are serious about improving.
Tracking Progress
Keep a simple log:
Date Contest Solved Rating Notes
---------- ----------- ------ ------ -----------------------
2024-01-15 Div2 #920 A,B,C 1247 Missed D by off-by-one
2024-01-18 Div2 #921 A,B 1220 Overcomplicated C
2024-01-20 Virtual #900 A,B,C,D -- D: segtree, new patternLook for patterns in what you miss. If you keep losing to the same category (e.g., greedy, DP transitions), that is your study priority.
Mental Game
Rating Anxiety
Your rating is a noisy signal. A single contest can swing +/- 100 based on:
- One misread problem.
- One off-by-one.
- Server lag on submit.
What matters is your 20-contest moving average. A bad contest means nothing if the trend is up.
Rating
1600 | *
1500 | * * *
1400 | * * * * * *
1300 | * * * *
1200 | * * *
1100 | *
+-----------------------------------------> Contests
The path to 2100 is not a straight line.Tilt Management
Tilt = emotional state where frustration degrades your performance. Symptoms:
- Submitting without testing.
- Changing random parts of code hoping it works.
- Rage-quitting a problem and moving to the next without thinking.
Fix: When you notice tilt, stop coding. Re-read the problem statement from scratch. Drink water. 60 seconds of doing nothing is cheaper than 10 minutes of panicked debugging.
Consistency Over Spikes
Doing 5 problems on a great day and 0 on a bad day averages worse than doing 2-3 problems consistently. The goal is to maximize your floor, not your ceiling.
Practical schedule for improvement:
Mon: Upsolve last contest (1-2 problems)
Tue: Practice topic you are weak on (1-2 problems)
Wed: Virtual contest OR rated contest
Thu: Upsolve (1-2 problems)
Fri: Practice weak topic (1-2 problems)
Sat: Rated contest (if available)
Sun: Rest or light practiceThat is 6-10 problems per week. At this rate, expect ~200-300 rating gain over 3-4 months if you are genuinely engaging with problems above your level.
Useful CF Features
Custom Invocation
Codeforces -> any problem -> Custom Invocation (bottom of page)
Paste your code, provide custom input, see output. Useful for quick testing without local setup. Limited to 15 seconds and 256 MB.
Problem Tags and Difficulty
Every CF problem has:
- Difficulty rating (e.g., 1400): calibrated to the rating at which ~50% of contestants solve it.
- Tags (e.g.,
dp,greedy,math): added after the contest. Use these to find practice problems by topic.
Problemset filter: Codeforces -> Problemset -> filter by rating range and tags
For targeted practice at 1100 aiming for 2100, grind problems in this order:
Phase 1 (1100-1400): problems rated 1200-1500
Phase 2 (1400-1700): problems rated 1500-1800
Phase 3 (1700-2100): problems rated 1800-2200Stay one bracket above your current rating. Solving problems at your rating teaches you nothing new.
Gym
Codeforces -> Gym
Full contest archives from ICPC regionals, national olympiads, and other competitions. Useful for team practice. Does not affect your rating.
Mashups
Codeforces -> Mashups -> Create new mashup
Build a custom contest from any CF problems. Useful for:
- Targeted topic practice (e.g., 10 problems tagged
segment tree, rated 1600-1900). - Team practice sessions.
- Simulating a contest with problems you have not seen.
Comparing Solutions
After a contest, go to the standings and click on fast solvers' handles. Read their solutions. You will learn idioms and approaches you would never discover on your own.
Useful Keyboard Shortcuts
On any problem page:
Ctrl+Enterin the code editor submits your solution.- The problem page itself has no shortcuts, but consider using CF-Tool or Competitive Companion browser extension to auto-download test cases.
Quick Reference: The 1100-to-2100 Roadmap
Rating Focus Areas
----------- ------------------------------------------------
1100 - 1300 Implementation, brute force, basic math,
greedy, sorting. Learn to read problems.
1300 - 1500 Binary search, two pointers, prefix sums,
basic DP (1D), basic graph (BFS/DFS).
1500 - 1700 Intermediate DP, DSU, segment tree basics,
number theory (mod inverse, sieve).
1700 - 1900 Bitmask DP, advanced greedy with proofs,
shortest paths, trees (LCA, Euler tour).
1900 - 2100 Segment tree with lazy propagation, flows,
advanced DP optimizations, string algorithms.
----------- ------------------------------------------------
At every level: stress testing, fast implementation, reading
problems carefully, and managing your mental state.What the Code Won't Teach You
Insights drawn from reflection notes
Upsolving is where your rating is actually made. Contests are performance events. Upsolving is the learning event. Most people treat the contest as the learning opportunity and skip upsolving. This inverts the leverage.
Mental state is not a "soft" factor. Tilt causes concrete, measurable performance degradation: submitting without testing, making random changes, spending 40 minutes on a problem you should have abandoned. Recognizing tilt in yourself and having a protocol to break it is a concrete skill with concrete payoff.
The stress test is for finding bugs, not proving correctness. 1000 passing random tests don't prove correctness -- some bugs only appear on adversarial inputs. Stress tests find random bugs. For adversarial bugs, you need explicit worst-case reasoning.
THE REAL WORKFLOW vs THE PERCEIVED WORKFLOW:
Perceived (what 1100 thinks matters):
+----------------------------------+
| Know algorithms --> Solve fast |
| (90% of effort) |
+----------------------------------+
Real (what 2100 actually does):
+----------------------------------------------+
| Read carefully --> Test thoroughly --> Code |
| (30% reading) (30% testing) (40%) |
| |
| + upsolve every contest |
| + manage mental state |
| + track weaknesses systematically |
+----------------------------------------------+Mental Traps
Integrated from reflection notes
Trap: "I'll build the stress test when I need it."
By the time you need a stress test, you've wasted 20 minutes debugging manually. The template (brute.cpp + gen.cpp + stress.sh) should be ready BEFORE the contest, not during.
Trap: "My implementation looks right, so it probably is."
Looking right and being right are different. Subtle bugs (wrong index, wrong sign, wrong operation order) make code look correct on a fast read-through but fail on specific inputs. The only reliable detector is testing, not staring.
Trap: "Virtual contests are less valuable than real contests."
The opposite is true. Virtual contests give time pressure without rating risk. The problem of "freezing under pressure" is only solvable by practicing under pressure.
Trap: "Reading the editorial means I know the solution."
Reading != knowing. You know the solution when you can implement it from scratch, get AC, and explain every line.
CONTEST DECISION FLOWCHART:
Problem opened
|
v
Read FULL statement + constraints + output format
|
v
+- Idea in < 5 min? --+
| YES | NO
v v
Code + test Skip, move to next problem
all samples |
| Come back if time remains
v
Edge cases (n=1, all same, max values)
|
v
Submit with HIGH CONFIDENCE
(not hope)Self-Test
Drawn from reflection notes
[ ] Do you have a working stress test template (brute + gen + runner) that you can copy and adapt in under 5 minutes? If not, build one today.
[ ] Count your last 10 WA submissions. How many were algorithm bugs vs implementation bugs (off-by-one, overflow)? If implementation bugs dominate, your workflow -- not your algorithm knowledge -- is the bottleneck.
[ ] When did you last make a random code change hoping it would fix a WA? If within the last 5 contests, that's a tilt habit to break. Protocol: write a comment stating what you think is wrong before changing code.
[ ] How many problems did you upsolve from your last 3 contests? Upsolving rate directly predicts rating trajectory.
[ ] Time yourself typing your contest template from memory. Target: under 2 minutes. If slower, you're losing time on boilerplate in every contest.
Further Reading
- How to practice Competitive Programming (Um_nik)
- Self-deception: maybe why you are still grey (Radewoosh)
- Competitive Programmer's Handbook (Laaksonen) -- free PDF
- See: Common Templates
- See: Debugging Under Pressure
The Underlying Lesson
The difference between a 1400 and a 1900 is rarely knowing more algorithms — it is having a workflow. The 1900 reads all problems first, estimates difficulty, picks the right order, tests before submitting, and never burns 30 minutes on a wrong approach without a checkpoint. Strategy is the invisible algorithm.
This file is meant to be internalized BEFORE a contest, not consulted during one. If you are reading it mid-round, you have already lost time.
Before You Code Checklist
- [ ] Read ALL problems first -- scan A through E/F before writing a single line. Mark estimated difficulty.
- [ ] Check constraints before choosing approach -- is
(sort OK) or (need linear)? - [ ] Write the approach in a comment before coding -- 2 sentences max. If you can't state it clearly, you don't understand it yet.
- [ ] Test on sample inputs AND one hand-crafted edge case before submitting. Minimum: empty input,
, max value. - [ ] Set a time checkpoint -- if stuck for 15 minutes with no progress, STOP. Re-read the problem, or switch to another problem and come back.
What Would You Do If...?
You've solved A and B in 20 minutes, but C looks like a hard math problem and D looks like standard DP. Do you attempt C in order, or skip to D? What factors determine your choice?
You submit B and get WA on test 3, with 1 hour 40 minutes remaining and C-E untouched. How much time do you allocate to debugging B before moving on?
You realize 5 minutes before the contest ends that your D solution has an off-by-one error, but you also have an untested solution for C ready to submit. Which do you prioritize?
The Mistake That Teaches
Round 814, problem C. You read the problem and it screams "greedy -- sort by deadline." You code it in 12 minutes, submit, WA on test 7. You stare at the code. It looks correct. You add random +1/-1 tweaks and resubmit. WA. WA. WA. Penalty stacks to +60 minutes.
After the contest, you read the editorial. The greedy was right -- but you sorted by the wrong key. You sorted by deadline when you should have sorted by profit-per-unit-time. The fix was changing one comparator line.
The lesson: When you get WA on a greedy, don't tweak constants -- re-examine your sorting key. Write down WHY your greedy is correct before coding. If you can't articulate the exchange argument in one sentence, your greedy might be wrong.
The shortest possible summary of this entire file: Read, Plan, Code, Test, Submit — and never skip a step under time pressure, because that is exactly when skipping costs the most.
See also: Study Plan | Debugging Under Pressure | Mistake Journal | Speed Drills