Source: EMC-2021-P1
Category: Extremal Problems

Problem: A draws a regular 2021-gon in the plane. B labels each vertex with a real number such that the labels on any two adjacent vertices differ by at most 1. For any two non-adjacent vertices whose labels differ by at most 1, A draws a diagonal connecting them. Let $d$ denote the number of diagonals drawn by A. Find the minimum possible value of $d$.

Answer: The answer is $2018$.

Reference solution:
The minimum possible value of $d$ is $2018$.

There exists a valid numbering of the vertices such that exactly $d = 2018$ diagonals are drawn.

We prove by induction that for a general $n$-gon ($n \ge 3$), A must draw at least $n-3$ diagonals. 
When $n=3$, the number of diagonals drawn is at least $3-3=0$, which is obvious. 
Assume the statement holds for $n-1$, and consider the case $n$. Let the label on vertex $v$ be $a$, which is the smallest among all labels, and let the labels on the two vertices adjacent to $v$, namely $v_1$ and $v_2$, be $b$ and $c$, respectively. Since the labels on adjacent vertices differ by at most $1$, we have $0 \le b-a \le 1$ and $0 \le c-a \le 1$. This implies that $|b-c| \le 1$, so $v_1$ and $v_2$ are connected by a diagonal. 

Remove vertex $v$ to obtain an $(n-1)$-gon; the segment $v_1v_2$ is an edge of this smaller polygon. By the induction hypothesis, this $(n-1)$-gon has at least $n-4$ diagonals. Adding the diagonal $v_1v_2$ shows that the original $n$-gon has at least $(n-4) + 1 = n-3$ diagonals. The induction is complete.

For $n=2021$, A must draw at least $2021-3 = 2018$ diagonals. Thus, the minimum possible value of $d$ is indeed $2018$.

Grading guidelines:
(Partial) 1. Gave a labeling achieving $d=2018$ (or in general $d=n-3$), and correctly checked that adjacent vertices differ by at most 1 and that exactly those $2018$ non-adjacent pairs with label difference at most 1 occur. 2. Proved the key structural step: if $v$ has minimal label $a$ and its neighbors have labels $b,c$, then $0\le b-a\le1$ and $0\le c-a\le1$, hence $|b-c|\le1$ and therefore $v_1v_2$ must be drawn. 3. Correctly set up the induction/reduction $n\to n-1$ by removing a vertex of minimal label so that $v_1v_2$ becomes an edge of the smaller polygon, even if the diagonal-count conclusion is not fully justified. (Almost) 1. Proved the lower bound $d\ge n-3$ (hence $d\ge2018$) by induction using the minimal-label vertex and deletion, but did not provide (or incorrectly verified) a construction achieving $2018$. 2. Gave both the construction and the inductive lower bound idea, but left a small gap in the induction step (e.g. not justifying that diagonals in the $(n-1)$-gon are also diagonals of the original $n$-gon, or double-counting/omitting the added diagonal $v_1v_2$). 3. Solution is almost complete, but made minor mistakes which are not negligible.

Construction task:
Provide an explicit labeling for the original regular 2021-gon: output exactly one Python expression which, when eval-ed, returns a list of 2021 real numbers (int/float), where the i-th entry is the label of vertex i (in cyclic order). The labels must satisfy that for every pair of adjacent vertices (including vertices 2021 and 1), the absolute difference of their labels is at most 1. Among all such labelings, your labeling must make the number of diagonals drawn by A (i.e., the number of unordered pairs of non-adjacent vertices whose labels differ by at most 1) as small as possible. Put the expression as the only content inside <construct>...</construct>.

Reference construction:
[i if i <= 1010 else 2020.5 - i for i in range(2021)]

Verifier code:
import sys, math, ast

def fail(msg: str):
    print(msg)
    sys.exit(0)

s = sys.stdin.read()
if s is None:
    fail("Parse error: empty input")
s = s.strip()
if not s:
    fail("Parse error: empty input")

# Parse as a Python expression (strict), then eval in restricted environment
try:
    tree = ast.parse(s, mode="eval")
except Exception as e:
    fail(f"Parse error: {e}")

try:
    codeobj = compile(tree, "<stdin>", "eval")
    val = eval(codeobj, {"__builtins__": {}, "range": range}, {})
except Exception as e:
    fail(f"Eval error: {e}")

# Check list length
if not isinstance(val, list):
    fail(f"Type error: expected a list, got {type(val).__name__}")
if len(val) != 2021:
    fail(f"Length error: expected 2021 labels, got {len(val)}")

# Check each element is int/float (reject bool and non-finite)
a = val
for idx, x in enumerate(a):
    if isinstance(x, bool) or not isinstance(x, (int, float)):
        fail(f"Element type error at index {idx}: expected int/float, got {type(x).__name__}")
    if not math.isfinite(float(x)):
        fail(f"Element value error at index {idx}: non-finite value {x!r}")

# Check adjacency constraints
n = 2021
for i in range(n):
    j = (i + 1) % n
    diff = abs(float(a[i]) - float(a[j]))
    if diff > 1 + 1e-12:
        fail(f"Adjacency constraint violated at indices ({i},{j}): values {a[i]!r}, {a[j]!r}, diff={diff}")

# Count diagonals
d = 0
for i in range(n):
    ai = float(a[i])
    for j in range(i + 1, n):
        # adjacent if consecutive or (0, n-1)
        if j == i + 1 or (i == 0 and j == n - 1):
            continue
        if abs(ai - float(a[j])) <= 1 + 1e-12:
            d += 1

if d != 2018:
    fail(f"Diagonal count incorrect: computed d={d}, expected 2018")

print("True")