486蛇形填充n阶方阵——题目思路与知识点总结 | 豆包MarsCode AI刷题

90 阅读3分钟

486蛇形填充n阶方阵——题目思路与知识点总结C++ | 豆包MarsCode AI刷题

写在前面:

这是我的第一篇C++刷题总结,今后将持续输出干货满满的刷题思路、方法、总结及心得体会。 刷题顺序优先考虑简单题,刷题顺序为给出的顺序的倒序。OK,下面进入正题。

题目要求

1、具体要求

在一个n×nn\times n的方阵中填入11nn 这些数字;按照蛇形顺序从右上角开始,沿着方阵的边界顺时针进行 填充。

2、输入输出

输入:int类型n,代表方阵行数/列数

输出:二维矩阵,元素为int类型

题目类型分析

这是一道典型的过程模拟题。并不涉及到什么算法,就是模拟过程,但却十分考察对代码的掌控能力。

思路

第一层逻辑

  • 初始化一个 n x n 的矩阵,所有元素初始化为 0
  • 定义四个方向的行列偏移量 (右, 下, 左, 上)
  • 初始化当前位置和方向索引
  • 初始化当前填充的数字
  • 循环填充

两层逻辑

  • 初始化一个 n x n 的矩阵,所有元素初始化为 0
  • 定义四个方向的行列偏移量 (右, 下, 左, 上)
  • 初始化当前位置和方向索引
  • 初始化当前填充的数字
  • 循环填充
    • 填充当前位置
    • 获取下一个位置
    • 判断是否需要改变方向,如果需要,则改变
    • 更新行列下标

将逻辑翻译为C++代码

#include <iostream>
#include <vector>

using namespace std;
vector<vector<int>> solution(int n) {
    // 初始化一个 n x n 的矩阵,所有元素初始化为 0  
    vector<vector<int>> matrix(n, vector<int>(n, 0));
      
    // 定义四个方向的行列偏移量 (右, 下, 左, 上)  
    vector<pair<int, int>> directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
      
    // 初始化当前位置和方向索引  
    int row = 0, col = n - 1;
    int direction_index = 0;
      
    // 初始化当前填充的数字  
    int num = 1;
      
    for (int i = 0; i < n * n; ++i) {
        // 填充当前位置  
        matrix[row][col] = num++;
          
        // 获取下一个位置  
        int next_row = row + directions[direction_index].first;
        int next_col = col + directions[direction_index].second;
          
        // 判断是否需要改变方向  
        if (next_row < 0 || next_row >= n || next_col < 0 || next_col >= n || matrix[next_row][next_col] != 0) {
            // 否则,改变方向(顺时针旋转)  
            direction_index = (direction_index + 1) % 4;
            next_row = row + directions[direction_index].first;
            next_col = col + directions[direction_index].second;
        }
        
        row = next_row;
        col = next_col;
    }
      
    return matrix;
}


int main() {
    vector<vector<int>> a1 = solution(4);
    cout << (a1 == vector<vector<int>>{{10, 11, 12, 1}, {9, 16, 13, 2}, {8, 15, 14, 3}, {7, 6, 5, 4}}) << endl;

    vector<vector<int>> a2 = solution(5);
    cout << (a2 == vector<vector<int>>{{13, 14, 15, 16, 1}, {12, 23, 24, 17, 2}, {11, 22, 25, 18, 3}, {10, 21, 20, 19, 4}, {9, 8, 7, 6, 5}}) << endl;

    vector<vector<int>> a3 = solution(3);
    cout << (a3 == vector<vector<int>>{{7, 8, 1}, {6, 9, 2}, {5, 4, 3}}) << endl;

    return 0;
}

代码细节剖析

  1. vector<pair<int, int>> :

    • 这是一个向量的声明,其中每个元素是一个pair<int, int>
    • pair<int, int>是一个包含两个int类型元素的结构体。通常用于表示二维坐标或偏移量。
  2. pair

pair结构体概述

pair是C++标准库中的一个模板类,位于<utility>头文件中。它用于将两个不同类型的对象组合成一个单一的对象。pair结构体通常用于需要同时返回两个值的函数,或者在需要存储两个相关值的场景中。

语法

#include <utility>  // 包含pair的头文件
std::pair<T1, T2> myPair;
  • T1 和 T2 是两个不同的类型。
  • myPair 是 pair 结构体的实例。

成员变量

pair结构体有两个成员变量:

  • first:第一个元素,类型为T1
  • second:第二个元素,类型为T2
  1. 细节逻辑

在“判断是否需要改变方向”逻辑中,用“或逻辑”比用“与逻辑”更加高效。

在循环中,用取余来控制行为逻辑也是一种很好的方法。

if (A) { 行为1 } 行为2

if (!A) { 行为2 } else { 行为1 }

更好