Source: APMO-2024-P2
Category: Counting

Problem: In a $100\\times100$ grid, let $(a,b)$ denote the cell in the $a$-th row and $b$-th column. For an integer $51\\leq k\\leq 99$, a $k$-knight moves one step horizontally or vertically and $k$ steps in the other direction. The $k$-knight starts at cell $(1,1)$. A moving sequence is a sequence of cells $(x_0,y_0)=(1,1)$, $(x_1,y_1)$, $\\cdots$, $(x_n,y_n)$ such that for $i=1$, $2$, $\\cdots$, $n$, $1\\leq x_i,y_i\\leq 100$, and the $k$-knight can move from $(x_{i-1},y_{i-1})$ to $(x_i,y_i)$. The cells $(x_i,y_i)$ are called reachable. For each $k$, find the number of reachable cells $L(k)$.

Answer: When $k$ is even, $L(k)=4k(100-k)$; when $k$ is odd, $L(k)=2k(100-k)$.

Reference solution:
We prove that for every integer $51 \le k \le 99$,
\[
L(k)=
\begin{cases}
4k(100-k), & k \text{ even},\\
2k(100-k), & k \text{ odd}.
\end{cases}
\]

First determine which cells can possibly be reached by one move from another cell. A cell $(x,y)$ is directly reachable from some other cell if and only if at least one of
\[
x-k\ge 1,\qquad x+k\le 100,\qquad y-k\ge 1,\qquad y+k\le 100
\]
holds. Equivalently,
\[
x\ge k+1 \quad\text{or}\quad x\le 100-k \quad\text{or}\quad y\ge k+1 \quad\text{or}\quad y\le 100-k. \tag{1}
\]
Indeed, a $k$-knight move changes one coordinate by $k$ and the other coordinate by $1$; hence, in order to land at $(x,y)$, one of the four cells obtained by changing either coordinate by $k$ must still lie on the board.

Therefore every cell satisfying
\[
101-k\le x\le k,
\qquad
101-k\le y\le k
\]
is unreachable. Let
\[
S=\{(x,y):101-k\le x\le k,\ 101-k\le y\le k\}.
\]
This is the central square of unreachable cells. Its side length is
\[
k-(101-k)+1=2k-100,
\]
so the number of cells outside $S$ is
\[
100^2-(2k-100)^2=4k(100-k). \tag{2}
\]
Thus $L(k)\le 4k(100-k)$.

We now show that all cells outside $S$ are reachable when $k$ is even, and exactly the cells outside $S$ with the same chessboard color as $(1,1)$ are reachable when $k$ is odd.

Color the board like a chessboard, according to the parity of $x+y$. A $k$-knight move changes $x+y$ by one of $\pm k\pm1$. Hence if $k$ is odd, every move preserves the color, while if $k$ is even, every move changes the color.

The key observation is that, outside $S$, one can move between same-colored neighboring cells by two $k$-knight moves. More precisely, suppose $(x,y)$ and one of $(x,y\pm2)$, $(x\pm2,y)$ both lie on the board and both satisfy condition (1). If the usable coordinate is on the lower side, for example $x\le 100-k$, then
\[
(x,y)\to (x+k,y\pm1)
       \to (x,y\pm2)
\]
is a legal two-move path whenever the displayed cells are on the board. If $x\ge k+1$, we instead use
\[
(x,y)\to (x-k,y\pm1)
       \to (x,y\pm2).
\]
Similarly, if $y\le 100-k$, then
\[
(x,y)\to (x\pm1,y+k)
       \to (x\pm2,y),
\]
and if $y\ge k+1$, then
\[
(x,y)\to (x\pm1,y-k)
       \to (x\pm2,y).
\]
Thus any allowed step by $(\pm2,0)$ or $(0,\pm2)$ between cells outside $S$ can be realized by two legal $k$-knight moves.

Since $S$ is a central square and $k\ge 51$, the cells outside $S$ form a frame around it. Within each chessboard color, this frame is connected by steps of the form $(\pm2,0)$ and $(0,\pm2)$. Starting from $(1,1)$, which lies outside $S$, the previous paragraph shows that every cell outside $S$ with the same color as $(1,1)$ is reachable.

If $k$ is odd, the color is preserved by every move, so no cell of the opposite color can be reached. The board has even side length, and the square $S$ also has even side length $2k-100$, so the cells outside $S$ are split equally between the two colors. Therefore
\[
L(k)=\frac12\bigl(100^2-(2k-100)^2\bigr)=2k(100-k).
\]

If $k$ is even, every move changes color. Let $(x,y)$ be any cell outside $S$ whose color is opposite to that of $(1,1)$. Since $(x,y)$ satisfies condition (1), it has a legal predecessor or successor by a $k$-knight move inside the board; that adjacent cell has the same color as $(1,1)$ and is also outside $S$. As shown above, that adjacent cell is reachable, so one more move reaches $(x,y)$. Hence every cell outside $S$ is reachable, and by (2)
\[
L(k)=100^2-(2k-100)^2=4k(100-k).
\]

This proves the desired formula.

Grading guidelines:
(Partial) 1. Identified the central square S of cells with 101−k≤x≤k and 101−k≤y≤k as unreachable (e.g. by proving a necessary condition for landing at (x,y): x≥k+1 or x≤100−k or y≥k+1 or y≤100−k). 2. Correctly counted the number of cells outside S as 100^2−(2k−100)^2=4k(100−k), obtaining the upper bound L(k)≤4k(100−k). 3. Made a correct parity/color observation: a k-knight move preserves chessboard color iff k is odd, and flips color iff k is even. (Almost) 1. Established reachability of all cells outside S of the same color as (1,1) by exhibiting the key two-move simulation of (±2,0) and (0,±2) steps between admissible cells, but did not fully justify that the outside-of-S frame is connected (within a color) by these steps. 2. Correctly derived the odd-k case L(k)=2k(100−k) from color preservation and the count of outside-of-S cells, but the argument that the outside-of-S cells split equally between the two colors is missing or flawed. 3. Correctly derived the even-k case L(k)=4k(100−k) from reachability of one color plus one extra move to the opposite color, but left a localized gap in proving every opposite-colored cell outside S has a valid adjacent (by a k-knight move) same-colored cell still outside S. 4. Solution is almost complete, but made minor mistakes which are not negligible.

Construction task:
For the specific case $k=68$, provide an explicit construction of a path from the starting cell $(1,1)$ to every reachable cell.

Construction requirements:
- The output must be a SINGLE valid Python expression that evaluates to a dictionary.
- The dictionary should map each reachable cell `(x, y)` to its corresponding path.
- A path must be represented as a list of tuples `[(1,1), (x_1, y_1), ..., (x, y)]`, where each consecutive pair of cells represents a valid move for a 68-knight on the $100 \times 100$ grid.
- Do not use any assignment statements, `import` statements, `for` loops (outside of comprehensions), or any non-expression syntax.
- You may use lambda functions, comprehensions, and dictionary unpacking to generate the paths algorithmically.
- Put ONLY the Python expression inside the `<construct>` block.

Reference construction:
(lambda adj: (lambda bfs: bfs(bfs, {}, {(1, 1): [(1, 1)]}))(
    lambda f, v, frontier: {**v, **frontier} if not frontier else f(
        f,
        {**v, **frontier},
        {n: frontier[u] + [n] for u in frontier for n in adj(u) if n not in v and n not in frontier}
    )
))(lambda u: [(u[0]+dx, u[1]+dy) for dx, dy in [(1,68), (1,-68), (-1,68), (-1,-68), (68,1), (68,-1), (-68,1), (-68,-1)] if 1<=u[0]+dx<=100 and 1<=u[1]+dy<=100])

Verifier code:
import sys

def verify():
    # Increase recursion limit to support deep recursive lambda functions (e.g., BFS implementations)
    sys.setrecursionlimit(20000)
    
    payload = sys.stdin.read().strip()
    if not payload:
        print("Empty payload.")
        return

    try:
        # The instruction specifies the output must be a SINGLE valid Python expression.
        # eval() enforces this and supports algorithmic generation (lambdas, comprehensions).
        paths_dict = eval(payload)
    except Exception as e:
        print(f"Failed to evaluate payload: {e}")
        return

    if not isinstance(paths_dict, dict):
        print(f"Payload evaluated to {type(paths_dict).__name__}, expected dict.")
        return

    # Check for the exact number of reachable cells for k=68 on a 100x100 grid
    # Formula: L(k) = 4k(100-k) -> 4 * 68 * 32 = 8704
    if len(paths_dict) != 8704:
        print(f"Dictionary contains {len(paths_dict)} keys, expected exactly 8704.")
        return

    for target, path in paths_dict.items():
        # Validate key format
        if not isinstance(target, tuple) or len(target) != 2:
            print(f"Key {target} is not a 2-tuple.")
            return
        
        tx, ty = target
        if type(tx) is not int or type(ty) is not int:
            print(f"Key {target} contains non-integer coordinates.")
            return
        
        # Validate path format
        if not isinstance(path, list):
            print(f"Path for {target} is not a list.")
            return
        
        if not path:
            print(f"Path for {target} is empty.")
            return

        if path[0] != (1, 1):
            print(f"Path for {target} does not start with (1, 1).")
            return
        
        if path[-1] != target:
            print(f"Path for {target} does not end with its key {target}.")
            return

        # Validate all cells in the path
        for cell in path:
            if not isinstance(cell, tuple) or len(cell) != 2:
                print(f"Cell {cell} in path for {target} is not a 2-tuple.")
                return
            x, y = cell
            if type(x) is not int or type(y) is not int:
                print(f"Coordinates of cell {cell} in path for {target} are not integers.")
                return
            if not (1 <= x <= 100 and 1 <= y <= 100):
                print(f"Cell {cell} in path for {target} is out of 100x100 grid bounds.")
                return

        # Validate consecutive moves in the path
        for i in range(len(path) - 1):
            x1, y1 = path[i]
            x2, y2 = path[i+1]
            dx = abs(x2 - x1)
            dy = abs(y2 - y1)
            
            # A valid 68-knight move must have absolute coordinate differences of exactly {1, 68}
            if {dx, dy} != {1, 68}:
                print(f"Invalid 68-knight move from {path[i]} to {path[i+1]} in path for {target}.")
                return

    print("True")

if __name__ == "__main__":
    verify()