DSA sheet / Introductory

Number Spiral

medium about 25 min mathimplementation
Open on CSES

The problem in brief

The positive integers fill an infinite grid in a spiral pattern that starts at the top-left cell (the statement shows the picture). For each of up to 100 000 queries you get a row y and column x, both up to a billion, and must print the number stored in that cell. Read the official statement for the exact shape of the spiral.

Try it

Tab indents; press Esc, then Tab, to leave the box. Ctrl+Enter runs.

Hints

Stuck? Reveal one hint at a time. Each nudges without giving away the next.

The walkthrough

Spoilers ahead: open a section only after you have given the hints a fair try.

How to think

When the input is too large to simulate, write out a small grid by hand (say 5 by 5) and stare at it until you see the structure. Here the structure is “nested L-shapes”: the first k layers together fill exactly the top-left k by k square, so they hold the numbers 1 to k^2. Layer k therefore holds (k-1)^2 + 1 up to k^2, a run of 2k - 1 consecutive numbers.

Once you know the range of a layer, everything reduces to “where in the run is my cell?”. The direction alternation (odd layers run one way, even layers the other) is the only annoying part; handle it with a parity check and verify against your small hand grid.

The habit: turn a picture into arithmetic by finding the level sets of the picture (here max(x, y)), then solve a one-dimensional indexing problem inside a level.

Intuition

The spiral is a snail shell growing outward. Every time the shell finishes a full k by k square, the next number written is k^2 + 1, which starts the next L-shape. Each L is walked from one end to the other, and which end it starts from alternates from layer to layer.

Approach

Let m = max(x, y) be the layer.

  • If the cell is on the row arm (y is at least x, so the row y = m): for odd m the value is (m-1)^2 + x; for even m it is m^2 - x + 1.
  • Otherwise the cell is on the column arm (x = m, y less than x): for even m the value is (m-1)^2 + y; for odd m it is m^2 - y + 1.

Test it on a small grid you build by simulation before trusting it: check the corner cells and the first row and column.

Pitfalls: m^2 reaches 10^18, which fits in a signed 64-bit integer but not in a JavaScript double, so use BigInt there; C++ and Java need long long / long.

Complexity

O(1) per query, so O(t) overall. Read all queries quickly and print with one buffered write.

Solutions

Written from scratch and checked by compiling and running each one against a brute force on random inputs. Fast input/output, the way you would submit it.

Show solutions (C++17, Python 3, Java 17, Node.js)
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int t;
    cin >> t;
    while (t--) {
        long long y, x;
        cin >> y >> x;
        long long m = max(x, y), ans;
        if (y >= x) {
            ans = (m % 2 == 1) ? (m - 1) * (m - 1) + x : m * m - x + 1;
        } else {
            ans = (m % 2 == 0) ? (m - 1) * (m - 1) + y : m * m - y + 1;
        }
        cout << ans << "\n";
    }
    return 0;
}

Problem: CSES Problem Set (Antti Laaksonen, University of Helsinki), CC BY-NC-SA 4.0. The explanations and code above are original (© Anupam Kumar).

Related problems

Back to the sheet