201412-2 Z字形扫描 25行代码(100分)

题目

在这里插入图片描述
对于下面的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字形扫描的结果。

思路

一开始我是暴力破解,一个个方向来,写出来64行,思路也不清晰,后来在网上看到一个思路,就是把转过来思考一下,如下图:
在这里插入图片描述
然后就发现,这就像一个数塔,总共有2*n - 1层,而且按Z顺序扫描的元素的下标都具有对称性,如下图解释:
在这里插入图片描述
可以看到每层从左往右,下标x递减,y递增,从右往左则相反,然后奇数层就是从左往右,偶数层从右往左,所以利用这些对称性,我们可以写出精简的代码。

代码
#include <bits/stdc++.h>
int arr[510][510];
int n;
void zScan(int lever,bool isEven){
    int x,y;//确定起点坐标
    x = lever > n ? n : lever;
    y = lever > n ? (lever - n + 1) : 1;
    char c;//选择输出间隔符号
    c = (x == n && y == n) ? '\n' : ' ';
    int times;//限制每层递减/递增次数
    times = lever >= n ? (n - (lever - n)) : lever;
    if(isEven) std::swap(x,y);//偶数层时,交换x,y即可得到起点坐标
    for(int i = 0; i < times; i++)//每层对起点坐标作用times次,然后输出对应元素即可
        printf("%d%c",isEven ? arr[x++][y--] : arr[x--][y++],c);
    return ;
}
int main(){
    std::cin >> n;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
            std::cin >> arr[i][j];
    for(int lever = 1; lever <= 2 * n - 1; lever++)//循环层数
        zScan(lever,lever % 2 == 0);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值