沿45°递增的n*n数组

沿45°递增的n*n数组

Mar 9, 2014
Coding
Algorithm

问题 #

给定一个n,求一个n*n的二维数组,该数组的值沿45°方向的斜线依次递增。如n=4时,数组为

  1   2   4   7
  3   5   8  11
  6   9  12  14
 10  13  15  16

思路 #

  • 从左上角的第一个格子,即 (0,0) 开始,按照规则,依次将 1 ~ n*n 的数字填入数组中。
  • 填完一个格子 (row,col) 后,就向左下方移动,即 (row+1, col-1)。
  • 判断新的格子是否超出了边缘,如果超出了边缘(即 row > n-1 || col < 0 ),则原路返回,直到该斜线的起点(即 row == 0 || col == n-1
  • 回退到边缘后,根据当前的位置,决定下一条斜线的起点
    • 如果是在上边缘且非右上角,则向右挪一格(col++)作为新斜线的起点。
    • 如果是在右边缘,则向下挪一格(row++)作为新斜线的起点

代码 #

//Problem:给定一个n,求一个n*n的二维数组,该数组的值沿45°方向的斜线依次递增.
//Author: JarvisChu
//Blog: zhujiangtao.com
//Date: 2024-6-14
#include <iostream>
#include <iomanip> // setw()

using namespace std;

int main(int argc, char* argv[])
{
    const int n = 4; // 数组大小 n
    int data[n][n];  // 数组

    // 将 1 ~ n*n 的数字按照斜45°的规则,依次填入数组中
    int row = 0, col = 0; // 从 data[0][0] 开始填,即作为第一条斜线的起点
    for(int i = 1; i <= n*n; i ++) {
        data[row][col] = i;

        // 向斜下方移动,即45°的方向
        row++;col--;

        // 走到边缘了,原路回退,直到该斜线的起点
        if (row > n-1 || col < 0 ) {
            while(row >0 && col < n-1) { //回退到边缘时,结束
                row--; col++; // 回退一步
            }

            // 回退到该斜线的起点后,决定下一个斜线的起点
            if (row == 0 && col < n-1) { // 回退到了上边缘,且非右上角,可以往后挪一格作为新的斜线起点
                col++;
            }else if(col >= n-1) { // 回退到了右边缘,需要往下挪一格作为新的斜线起点
                row++;
            }
        }
    }

    //打印结果
    for(int i=0;i<n;i++){
        for(int j=0;j< n;j++){
            cout<<setw(3)<<data[i][j]<<" ";
        }
        cout<<endl;
    }
    return 0;
}

Updated at 2024-06-14