Finding an element in a 2d array given its position on a spiral

一世执手 提交于 2020-03-05 02:10:33

问题


I am trying to solve a problem which involves a spiral ordering of the elements of a matrix and how to calculate the corresponding row and column.

All the queries are in the form SZ P, where SZ is the size of the matrix and P the position in spiral starting from the center and ending in the top right corner.
The output has to be the cartesian coordinates (row and column) of the P point in the spiral (starting with line 1 at the bottom and column 1 at the left).

What I did to solve it, is doing it in reverse way, starting from the right corner and going on until the center):

while(k <= SZ && l <= SZ && m > 0 && n > 0)
{
right:
    for(int i = k; i <= m; ++i) /// right
    {
        a[i][m] = no;
        --no;
    }
    --m;
down:
    for(int i = m; i >= k; --i) /// down
    {
        a[n][i] = no;
        --no;
    }
    --n;
left:
    for(int i = n; i >= k; --i) /// left
    {
        a[i][k] = no;
        --no;
    }
    ++k;
up:
    for(int i = k; i <= m; ++i) /// up
    {
        a[l][i] = no;
        no--;
    }
    ++l;
    ///where l,k,n,m are:
    /// k start row index
    /// n end row index
    /// l start column index
    /// m end column index
}

The code works well on a 3x3 matrix, it outputs this matrix:

3 2 9
4 1 8
5 6 7

So, what I'm trying to find out now is how to find the cartesian coordinates of the point P in matrix without storing the matrix in memory, because the size limit is 100000.

Example Input:

3 1
3 3
3 9
5 9
5 10

Example Output:

Line = 2, column = 2.
Line = 3, column = 1.
Line = 3, column = 3.
Line = 4, column = 4.
Line = 5, column = 4.

回答1:


Augmenting the spiral slightly, a pattern emerges...

 31  30  29  28  27  26
 32  13  12  11  10 (25)
 33  14  03  02 (09) 24
 34  15 (04)[01] 08  23
 35 (16) 05  06  07  22
(36) 17  18  19  20  21

Squares of odd numbers 1^2, 3^2, 5^2 are located on the NorthEast facing diagonal, and squares of even numbers on SouthWest facing diagonal.

Also between any N^2, (N+1)^2 there are 2N(+1) elements; the first N are located on horizontal line and the rest on vertical line.

Placing the first item (N=1) at x=0, y=0, the coordinate for nth item is:

void spiral_to_cartesian(int &x, int &y, int n)
{
    x = 0; y=0;
    if (n <= 1)  return;
    int a = sqrt((double)n);
    int remainder = n - a*a;
    if (a & 1)
    {
       x+=(a/2); y-=(a/2);
       if (remainder > 0 && remainder <= n)
       {
          --y; x-=remainder-1;
       }
       else if (remainder > n)
       {
          x-=n; y+=remainder - n - 1;
       }
    }
    else
    {
       x-=(a/2); y+=(a/2)-1;
       if (remainder > 0 && remainder <= n)
       {
          ++y; x+=remainder-1;
       }
       else if (remainder > n)
       {
          x+=n; y-=remainder - n - 1;
       }
    }
}


来源:https://stackoverflow.com/questions/45915785/finding-an-element-in-a-2d-array-given-its-position-on-a-spiral

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!