#include <iostream>
using namespace std;
const int N = 500;
int a[N + 10][N + 10];
void inputMatrix(int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
cin >> a[i][j];
}
}
}
void printMatrixByZShape_1(int row, int col)
{
if (row == 0 || col == 0)
return;
if (row == 1) // 只有一行
{
for (int j = 0; j < col; j++)
cout << a[0][j] << " ";
return;
}
if (col == 1) // 只有一列
{
for (int i = 0; i < row; i++)
cout << a[i][0] << " ";
return;
}
// 多行多列
bool rightUp = false; // 右上走
bool leftDown = true; // 左下走
int i = 0, j = 1;
cout << a[0][0] << " ";
while (true)
{
cout << a[i][j] << " "; // 先把第一行输出
if (i == row - 1 && j == col - 1)
return;
if (leftDown) // 先往左下角遍历
{
if (j == 0 || i == row - 1) // 如果到达往左下角遍历的边界:最左边列 j = 0、最后一行 i = row-1
{
if (i != row - 1) // 还未到达下边界(最后一行)
i++; // 还可以向下遍历一个元素
else // 最后一行且到达了左边界:i == row - 1
j++; // 只能水平向右遍历一个元素
// 改变遍历的方向:从左下角-->右上角
leftDown = false;
rightUp = true;
}
else
i++, j--; // 没有到达边界,往左下角遍历
}
else // (rightUp = true)开始往右上角遍历
{
if (i == 0 || j == col - 1) // 如果到达往左下角遍历的边界:最右边列 j = col-1、第一行 i = 0
{
if (j != col - 1) // 还未到达右边界
j++; // 还可以向右遍历一个元素
else // 第一行且到达右边界
i++; // 只能向下遍历一个元素
// 改变遍历的方向:从右上角-->左下角
rightUp = false;
leftDown = true;
}
else
i--, j++; // 没有达到边界,继续往右上角遍历
}
}
}
int main(int argc, char const *argv[])
{
std::ios::sync_with_stdio(false);
int n;
cin >> n;
inputMatrix(n, n);
printMatrixByZShape_1(n, n);
return 0;
}
改进版:将方向判断变量取消,改用当前位置的横纵坐标和的奇偶性判断遍历的方向。
若i+j
为偶数,则下一个元素在其右上方;为奇数时,下一个元素在左下方,此时仍需处理边界值情况
#include <iostream>
using namespace std;
const int N = 500;
int a[N + 10][N + 10];
void inputMatrix(int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
cin >> a[i][j];
}
}
}
void printMatrixByZShape_2(int row, int col)
{
if (row <= 0 || col <= 0)
return;
int i = 0, j = 0;
while (true)
{
cout << a[i][j] << " "; // 先把第一行输出
if (i == row - 1 && j == col - 1)
return;
// 等价于:(i + j) % 2 != 0
if ((i + j) & 0x1 != 0) // 当前位置的横纵坐标和为奇数-->向左下方遍历
{
if (j == 0 || i == row - 1) // 如果到达往左下角遍历的边界:最左边列 j = 0、最后一行 i = row-1
{
if (i != row - 1) // 还未到达下边界(最后一行)
i++; // 还可以向下遍历一个元素
else // 最后一行且到达了左边界:i == row - 1
j++; // 只能水平向右遍历一个元素
}
else
i++, j--; // 没有到达边界,往左下角遍历
}
else // 当前位置的横纵坐标和为偶数-->向右上方遍历
{
if (i == 0 || j == col - 1) // 如果到达往左下角遍历的边界:最右边列 j = col-1、第一行 i = 0
{
if (j != col - 1) // 还未到达右边界
j++; // 还可以向右遍历一个元素
else // 第一行且到达右边界
i++; // 只能向下遍历一个元素
}
else
i--, j++; // 没有达到边界,继续往右上角遍历
}
}
}
int main(int argc, char const *argv[])
{
std::ios::sync_with_stdio(false);
int n;
cin >> n;
inputMatrix(n, n);
printMatrixByZShape_2(n, n);
return 0;
}