Z字形扫描
题目链接
在图像编码的算法中,需要将一个给定的方形矩阵进行 Z 字形扫描(Zigzag Scan)。
给定一个 n×n 的矩阵,Z 字形扫描的过程如下图所示:
对于下面的 4×4 的矩阵,
1 5 3 9
3 7 5 6
9 4 6 4
7 3 1 3
对其进行 Z 字形扫描后得到长度为 16 的序列:1 5 3 9 7 3 9 5 4 7 3 6 6 4 1 3。
请实现一个 Z 字形扫描的程序,给定一个 n×n 的矩阵,输出对这个矩阵进行 Z 字形扫描的结果。
输入格式
输入的第一行包含一个整数 n,表示矩阵的大小。
输入的第二行到第 n+1 行每行包含 n 个正整数,由空格分隔,表示给定的矩阵。
输出格式
输出一行,包含 n×n 个整数,由空格分隔,表示输入的矩阵经过 Z 字形扫描后的结果。
数据范围
1≤n≤500,
矩阵元素为不超过 1000 的正整数。
输入样例:
4
1 5 3 9
3 7 5 6
9 4 6 4
7 3 1 3
输出样例:
1 5 3 9 7 3 9 5 4 7 3 6 6 4 1 3
算法分析
这里我们有两种方法,一种是直接根据行走路线进行模拟,另一种是根据当前坐标和来输出根据对角线来进行模拟
代码实现
第一种方法模拟行进路线
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=505;
int map[maxn][maxn];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>map[i][j];
int x=1,y=1;
bool fx=true;//true表示往左下走,false表示往右上走
while(x<=n||y<=n)
{
if(x<=n&&y<=n)//这里要同时满足因为,有可能一个出界了
cout<<map[x][y]<<' ';
if(fx)
x--,y++;
else
x++,y--;
if(x<1)//到最右上了,换左下方向
{
fx=false;
x=1;
}
if(y<1)//到最左下了,换右上方向
{
fx=true;
y=1;
}
}
return 0;
}
第二种利用数组坐标找规律,利用坐标和在一条对角线上的时候,横纵坐标和是一样的
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=505;
int map[maxn][maxn];
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>map[i][j];
for(int i=2;i<=n*2;i++)//i代表横纵坐标和
{
if(i%2==0)
{
for(int j=i-1;j>=0;j--)//j代表行,i-j代表列,看你怎么看了,也可以换过来
{
if(j>=1&&j<=n&&i-j>=1&&i-j<=n)
cout<<map[j][i-j]<<' ';
}
}
else
{
for(int j=1;j<=i-1;j++)
{
if(j>=1&&j<=n&&i-j>=1&&i-j<=n)
cout<<map[j][i-j]<<' ';
}
}
}
}