Skip to content

Python for Competitive Programming

In one sentence

Every solution has the same shape: read the input line by line, compute, and print each answer. This page collects the Python you need for that, and the traps that cost points.

1. What problem does it solve?

Example — 2191A · Array Coloring (Raymond's first Accepted, 22 Jan)

\(n\) cards lie in a row, card \(i\) shows \(a_i\), and all \(a_i\) are different (each between \(1\) and \(n\)). Colour every card red or blue so that

  1. any two neighbouring cards in the row have different colours, and
  2. after sorting the cards by their numbers, any two neighbours in sorted order also have different colours.

Is that possible? Limits: \(t \le 200\), \(n \le 100\).

Input          Output
4
4
2 3 4 1        YES
3
2 3 1          NO
5
3 4 1 2 5      YES
5
3 1 4 2 5      NO

Thinking. Rule 1 forces the colours to alternate along the row, so a card's colour is decided by whether its position \(i\) is odd or even. Rule 2 forces them to alternate in sorted order. Since the numbers are exactly \(1..n\), the card showing \(a_i\) is at sorted position \(a_i\), so its colour is decided by whether \(a_i\) is odd or even. Both can hold only if \(i\) and \(a_i\) have the same parity relationship for every card: \((i - a_i) \bmod 2\) is the same for all \(i\).

First test, 2 3 4 1: \(i - a_i = -1, -1, -1, 3\), all odd. YES. Second test, 2 3 1: \(-1, -1, 2\), mixed. NO.

The code needs only the basics: read \(t\) test cases, read a list, loop, test parity with %, and print. All of that is below.

2. The skeleton

Every lesson file starts from this template. Here it is from July 19:

import sys

input = sys.stdin.readline


# sys.setrecursionlimit(300000)


def solve():
    n = int(input())

    return


t = 1
# t = int(input())
for _ in range(t):
    solve()
line why
input = sys.stdin.readline the built-in input() is slow for \(10^5\) lines; readline is much faster
# sys.setrecursionlimit(300000) uncomment only for deep recursion (see DFS)
def solve(): one test case; local variables inside a function are also faster
t = 1 / # t = int(input()) switch to the second line when the input starts with the number of test cases

3. Reading input

input line code
5 n = int(input())
3 7 n, k = map(int, input().split())
3 2 5 a = list(map(int, input().split()))
#..# (a string / grid row) s = input().strip()
\(n\) grid rows grid = [input().strip() for _ in range(n)]
1.5 2.5 x, y = map(float, input().split())

readline keeps the newline

sys.stdin.readline() returns "abc\n", not "abc". For numbers it does not matter, because int() and split() ignore it. For strings, always .strip(). Our August 2 lesson showed this:

def solve():
    # input string
    s = input()
    t = input().strip()

    print(len(s), len(t))

    if s == t:
        print("YES")
    else:
        print("NO")

With input abc and abc, it prints 4 3 and then NO: s still has the "\n".

4. Printing output

want code prints
one value per line print(x) 5
several values, one line print(a, b) 5 7
values from a loop, one line print(x, end=" ") inside the loop, then print() 3 10 5 …
no separator print(ch, end="") inside the loop, then print() LDDR
a formatted float print(f"{x:.6f}") 3.141593

5. Numbers

operation example result note
integer division 7 // 2 3 rounds down: -7 // 2 is -4
true division 7 / 2 3.5 always a float; avoid for large integers
remainder 7 % 2 1 the result has the sign of the divisor: -7 % 2 is 1
power 2 ** 10 1024
big integers 10 ** 30 exact Python int never overflows
modulo arithmetic (a * b) % MOD apply % after every step in counting problems

n / 2 where you meant n // 2

/ gives a float. For \(n\) around \(10^{17}\) a float cannot represent every integer, so answers silently go wrong. Use // for integers.

6. Lists and 2D lists

Our June 28 lesson checked how to build a 2D list safely:

def solve():
    a = [[0] * 3 for _ in range(3)]

    print(a)

    a[0][0] = 1

    print(a)

It prints [[0, 0, 0], [0, 0, 0], [0, 0, 0]] and then [[1, 0, 0], [0, 0, 0], [0, 0, 0]]: only row \(0\) changed.

The tempting shortcut a = [[0] * 3] * 3 is wrong. It makes one row and three references to it, so a[0][0] = 1 changes every row to [1, 0, 0]. Always use the list comprehension.

7. The containers you will use

container create main operations cost used for
list [0] * n a[i], append, pop() \(O(1)\) arrays, stacks, adjacency lists
set set() add, remove, x in s \(O(1)\) avg "have I seen this?", deleting edges (lesson notes)
dict {} d[k], d.get(k, 0), k in d \(O(1)\) avg counting, mapping values to indices
collections.Counter Counter(a) c[x] (missing → 0) \(O(1)\) avg frequency counts
collections.defaultdict defaultdict(list) d[k].append(v) \(O(1)\) avg groups, graphs with unusual labels
collections.deque deque() append, popleft, appendleft \(O(1)\) the BFS queue
heapq on a list q = [] heappush(q, x), heappop(q) \(O(\log n)\) smallest-first: Dijkstra
bisect on a sorted list bisect_left(a, x) \(O(\log n)\) counting ≤ / < x

heapq is a min-heap. For a max-heap, push -x and negate when popping.

Sorting, including key=lambda, is on Sorting & Greedy.

8. Worked solution — Array Coloring

The skeleton from §2 with t = int(input()) switched on. Positions are \(1..n\) in the statement; in Python a[i] has index \(i = 0..n-1\), so the position is i + 1.

import sys

input = sys.stdin.readline


def solve():
    n = int(input())
    a = list(map(int, input().split()))

    first = (1 - a[0]) % 2
    ok = True
    for i in range(n):
        if (i + 1 - a[i]) % 2 != first:
            ok = False

    if ok:
        print("YES")
    else:
        print("NO")


t = int(input())
for _ in range(t):
    solve()

% in Python never returns a negative number (-1 % 2 is 1), so (i + 1 - a[i]) % 2 is always \(0\) or \(1\) and the comparison is safe.

9. Common mistakes

Using the built-in input() on big inputs

Reading \(2 \cdot 10^5\) lines with the built-in input() can take longer than the whole algorithm. Put input = sys.stdin.readline at the top.

Forgetting t = int(input())

Most Codeforces problems start with the number of test cases. The skeleton has t = 1 by default, so switch lines.

Comparing strings that still have \n

See §3. .strip() every string you read.

Shadowing built-ins

sum = 0, max = a[0], list = [...] overwrite Python's functions, and a later sum(a) crashes. Pick other names (total, best, arr).

[[0] * m] * n

Every row is the same list (§6).

State left over between test cases

If solve() runs \(t\) times, create lists inside solve(), sized by this test's \(n\).

10. Practice

Problem Where Point
2191A · Array Coloring Codeforces, Jan 22 this page
2191B · MEX Reordering Codeforces, Jan 23 (WA, then AC) counting, then careful output
2227A · Koshary Codeforces, May 22 basic I/O
2227B · Party Monster Codeforces, May 22 reading strings
1742C · Stripes 4-Misc · I read a grid with strip()
1791C · Prepend and Append 3-TwoPointers · A string indexing

Credits & licenses
  • §2, §3 and §6 quote our lesson code. Everything else (the Array Coloring analysis, tables, mistakes) is ours.