非官方题解 | 蛇皮矩阵
2026-02-07 10:43:44
发布于:广东
2阅读
0回复
0点赞
题目分析
题目要求
输入整数 n,输出 n×n 的蛇皮矩阵:按行遍历,奇数行从左到右填充数字,偶数行从右到左填充数字。
核心思路
- 矩阵填充规则:奇数行正向(列号1→n)、偶数行反向(列号n→1)
- 数字范围:1 ~ n²,按填充顺序依次递增
- 输出要求:按行输出,每行n个数字,空格分隔
方法1:
#include <bits/stdc++.h>
using namespace std;
int n;
int main () {
cin >> n;
// 定义n×n的矩阵,初始值为0(数组大小110适配n≤100的限制)
int a[110][110] = {0};
int num = 1; // 填充的数字,从1开始
// 第一步:填充蛇皮矩阵
for (int i = 1; i <= n; i++) { // i表示当前行号(从1开始)
if (i % 2 != 0) { // 奇数行:正向填充(左→右)
for (int j = 1; j <= n; j++) {
a[i][j] = num++;
}
} else { // 偶数行:反向填充(右→左)
for (int j = n; j >= 1; j--) {
a[i][j] = num++;
}
}
}
// 第二步:输出矩阵
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cout << a[i][j] << " ";
}
cout << endl; // 每行输出完换行
}
return 0;
}
代码详解
1. 变量定义
int a[110][110] = {0}:定义二维数组存储矩阵,大小110×110满足题目n≤100的限制,初始值置0避免随机值干扰。int num = 1:用于填充矩阵的数字,初始为1,每填充一个位置自增1。
2. 矩阵填充逻辑
外层循环 for (int i = 1; i <= n; i++) 遍历每一行:
- 奇数行(i%2≠0):列号j从1到n循环,依次填充num,例如n=4时,第1行填充1、2、3、4。
- 偶数行(i%2=0):列号j从n到1循环,依次填充num,例如n=4时,第2行填充8、7、6、5。
3. 矩阵输出逻辑
双层循环按行输出:
- 外层循环遍历行号i,内层循环遍历列号j。
- 每个数字后输出空格,每行结束后输出换行符,保证格式符合题目要求。
测试用例验证
输入
4
执行过程
- 第1行(奇数行):j=1→4,填充1、2、3、4(num从1→5)
- 第2行(偶数行):j=4→1,填充8、7、6、5(num从5→9)
- 第3行(奇数行):j=1→4,填充9、10、11、12(num从9→13)
- 第4行(偶数行):j=4→1,填充16、15、14、13(num从13→17)
输出
1 2 3 4
8 7 6 5
9 10 11 12
16 15 14 13
复杂度分析
- 时间复杂度:O(n²),需要填充n²个数字,再输出n²个数字,两次双层循环均为O(n²)级别。
- 空间复杂度:O(n²),使用了n×n的二维数组存储矩阵(实际可优化为O(1),直接输出无需存储,见拓展思路)。
方法1总结
- 蛇皮矩阵的核心是行号奇偶性决定填充方向:奇数行正向、偶数行反向。
- 基础实现通过二维数组存储矩阵,逻辑清晰易理解,适合新手掌握。
- 优化方案可省去矩阵存储,直接计算数字并输出,节省空间(尤其适合n较大的场景)。
一、题目理解
题目核心要求
给定一个整数 n,需要生成并输出一个 n×n 的蛇皮矩阵。蛇皮矩阵的定义是:按行遍历填充数字,奇数行从左到右依次填充,偶数行从右到左依次填充,最终输出完整的矩阵。
输入输出示例
- 输入:
4 - 输出:
1 2 3 4 8 7 6 5 9 10 11 12 16 15 14 13
二、解题思路
- 矩阵存储:使用二维数组
a[110][110]存储矩阵(数组大小设为110是为了适配题目中n≤100的数据范围)。 - 数字填充规则:
- 定义变量
num从1开始,作为填充矩阵的连续数字。 - 遍历每一行:若为奇数行(行号
i%2≠0),列号从1到n正向填充;若为偶数行(行号i%2=0),列号从n到1反向填充。
- 定义变量
- 矩阵输出:按行遍历二维数组,逐行输出每个位置的数字,每行内数字用空格分隔。
三、方法2:
#include <bits/stdc++.h>
using namespace std;
int n;
int main () {
cin >> n;
// 定义二维数组存储矩阵,初始值置0避免随机值干扰
int a[110][110] = {0};
// 用于填充矩阵的数字,从1开始递增
int num = 1;
// 第一步:按蛇皮规则填充矩阵
for (int i = 1;i <= n;i++) {
// 奇数行:列从1到n,正向填充
if (i % 2 != 0) {
for (int j = 1;j <= n;j++) {
a[i][j] = num++;
}
}
// 偶数行:列从n到1,反向填充
else{
for (int j = n;j >= 1;j--) {
a[i][j] = num++;
}
}
}
// 第二步:输出填充完成的矩阵
for (int i = 1;i <= n;i++) {
for (int j = 1;j <= n;j++) {
cout << a[i][j] << " ";
}
// 每行输出完毕后换行
cout << endl;
}
return 0;
}
四、代码逐行解析
| 代码片段 | 功能说明 |
|---|---|
int a[110][110] = {0}; |
定义二维数组,大小110×110满足n≤100的限制,初始化为0避免垃圾值。 |
int num = 1; |
初始化填充数字为1,后续每填充一个位置自增1。 |
for (int i = 1;i <= n;i++) |
外层循环遍历矩阵的每一行,i 表示行号(从1开始)。 |
if (i % 2 != 0) |
判断当前行是否为奇数行,奇数行执行正向填充逻辑。 |
for (int j = 1;j <= n;j++) { a[i][j] = num++; } |
奇数行填充:列号j从1到n,依次将num赋值给a[i][j],赋值后num自增。 |
else { for (int j = n;j >= 1;j--) { a[i][j] = num++; } } |
偶数行填充:列号j从n到1,反向赋值,保证数字连续递增。 |
for (int i = 1;i <= n;i++) |
外层循环控制输出的行。 |
for (int j = 1;j <= n;j++) { cout << a[i][j] << " "; } |
内层循环输出当前行的所有列,数字后加空格分隔。 |
cout << endl; |
每行输出完成后换行,保证输出格式符合要求。 |
五、复杂度分析
- 时间复杂度:O(n²)。填充矩阵需要遍历n×n个位置,输出矩阵也需要遍历n×n个位置,两次双层循环的时间复杂度均为O(n²),总复杂度为O(n²)。
- 空间复杂度:O(n²)。主要消耗来自存储矩阵的二维数组
a,占用n×n的空间。
六、优化思路(可选)
上述代码需要存储完整矩阵,可优化为无需存储矩阵,直接输出,节省空间(空间复杂度降为O(1)):
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, num = 1;
cin >> n;
for (int i = 1; i <= n; i++) {
if (i % 2 != 0) {
// 奇数行直接输出
for (int j = 1; j <= n; j++) cout << num++ << " ";
}else{
// 偶数行计算起始值,反向输出
int start = num + n - 1;
for (int j = 1; j <= n; j++) cout << start-- << " ";
num += n;
}
cout << endl;
}
return 0;
}
方法2总结
- 蛇皮矩阵的核心是行号奇偶性决定填充方向:奇数行正向、偶数行反向。
- 基础实现通过二维数组存储矩阵,逻辑清晰,适合新手理解;优化版可省去矩阵存储,直接计算输出,空间效率更高。
- 代码的关键是通过双层循环控制行列遍历方向,保证数字连续且填充顺序符合题目要求。
这里空空如也






有帮助,赞一个