You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

螺旋矩阵第N步坐标求解:现有算法效率优化需求

Efficient Solution for Spiral Matrix Coordinate Lookup

Hey there! The problem with your current approach is that it simulates every step of the spiral, which becomes way too slow when dealing with enormous grid sizes (like 1e9+) and target values. Instead of looping through each layer, we can use mathematical calculations to directly find which layer the target value is in, then compute its coordinates in constant time O(1) (with binary search for layer detection, it's O(log(gridSize))—negligible even for the largest inputs).

Here's the Breakdown of the Efficient Approach:

  1. Identify the Layer of the Target Value
    The spiral matrix can be thought of as concentric square layers. The outermost layer is layer 0, the next inner is layer 1, and so on. The total number of steps up to the end of layer k-1 (i.e., all layers outside layer k) can be calculated with the formula:
    cumulative_steps = 4 * k * (gridSize - k)
    We use binary search to find the largest k where this cumulative step count is less than the target value. This tells us exactly which layer the target resides in, and the remaining steps within that layer.

  2. Find the Starting Coordinates of the Layer
    For layer k, the starting position (where the layer begins its spiral) is:

    • start_x = k + 1
    • start_y = k
      Each inner layer is shifted 1 row and 1 column inward from the previous layer, which gives us this starting point.
  3. Calculate the Exact Coordinates Using the Offset
    Once we have the remaining steps (offset) within the current layer, we determine which side of the square the target is on:

    • Rightward side: Offset from 1 to s (side length of the layer) → Coordinates: (start_x, start_y + offset)
    • Downward side: Offset from s+1 to s + (s-1) → Coordinates: (start_x + (offset - s), start_y + s)
    • Leftward side: Offset from s + (s-1) + 1 to s + 2*(s-1) → Coordinates: (start_x + (s-1), start_y + s - (offset - s - (s-1)))
    • Upward side: Offset from the remaining steps to 4*(s-1) → Coordinates: (start_x + (s-1) - (offset - s - 2*(s-1)), start_y)

Optimized Code Implementation

#include <iostream>
#include <sstream>

void GetSpiralFinalCoordinates(const unsigned long long gridSize, const unsigned long long finalDestSteps, 
                               unsigned long long& x, unsigned long long& y) {
    if (finalDestSteps == 0) { // Edge case (though input starts at 1 per problem description)
        x = 1;
        y = 0;
        return;
    }

    // Binary search to find the layer containing the target
    unsigned long long low = 0;
    unsigned long long high = gridSize / 2;
    unsigned long long best_layer = 0;
    unsigned long long total_up_to_best = 0;

    while (low <= high) {
        unsigned long long mid = low + (high - low) / 2;
        unsigned long long s_mid = gridSize - 2 * mid;
        if (s_mid <= 0) {
            high = mid - 1;
            continue;
        }
        unsigned long long cumulative = 4 * mid * (gridSize - mid);
        if (cumulative < finalDestSteps) {
            best_layer = mid;
            total_up_to_best = cumulative;
            low = mid + 1;
        } else {
            high = mid - 1;
        }
    }

    unsigned long long remaining = finalDestSteps - total_up_to_best;
    unsigned long long layer = best_layer;
    unsigned long long s = gridSize - 2 * layer;
    unsigned long long start_x = layer + 1;
    unsigned long long start_y = layer;

    // Determine which side and compute coordinates
    if (remaining <= s) {
        // Rightward movement
        x = start_x;
        y = start_y + remaining;
    } else if (remaining <= s + (s - 1)) {
        // Downward movement
        remaining -= s;
        x = start_x + remaining;
        y = start_y + s;
    } else if (remaining <= s + 2 * (s - 1)) {
        // Leftward movement
        remaining -= s + (s - 1);
        x = start_x + (s - 1);
        y = start_y + s - remaining;
    } else {
        // Upward movement
        remaining -= s + 2 * (s - 1);
        x = start_x + (s - 1) - remaining;
        y = start_y;
    }
}

int main() {
    unsigned long long x, y;
    unsigned long long a, b;
    std::string line;
    std::getline(std::cin, line);
    std::istringstream issline(line);
    issline >> a;
    issline >> b;
    GetSpiralFinalCoordinates(a, b, x, y);
    std::cout << x << " " << y << std::endl;
    return 0;
}

Why This Works for Large Values

This approach avoids any loops that scale with the grid size. Binary search for layer detection takes only ~30 iterations even for gridSize = 1e9, and the rest of the logic is just arithmetic operations. It handles ultra-large inputs (like gridSize=1073741824 and target=1152921504603393520) easily within the 1-second time limit.

Testing the Example

For gridSize=8 and finalDestSteps=53:

  • Binary search finds that cumulative steps up to layer 1 is 48, so remaining steps = 53-48=5
  • Layer 2 has a side length of 4. The remaining 5 steps fall in the downward side of the layer
  • Calculated coordinates: (3+1, 2+4) = (4,6), which matches manual calculation of the spiral path.

内容的提问来源于stack exchange,提问作者Vinícius

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:39:54