xdojZ字形扫描(数组/程序设计)

题目
标题
Z字形扫描

类别
数组

时间限制
1S

内存限制
256Kb

问题描述
在图像编码的算法中,需要将一个给定的方形矩阵进行Z字形扫描(Zigzag Scan)。给定一个m×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。分成两个部分。*/

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int n,a[100][100],i=0,j=0;  //x代表行数,y代表列数而不是横纵坐标,i,j是计数器
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        for(j=0;j<n;j++)
        {
            scanf("%d",&a[i][j]);
        }
    }
    printf("%d ",a[0][0]);
    int x=0,y=1;
    for(i=1;i<n;i++)    /*此时i代表长度递增的行序数,从0开始,使其与扫描时移动的次数
                        (也就是行的长度)相等,从第0行到第n-1行,共n行*/
    {
        if(i&1) //将每一斜行看作一行。若i&1==1,则i为奇数。奇数行的扫描方向为左下。
        {
            for(j=0;j<i;j++)    //扫描第i行时向左下移动的次数为i
            {
                printf("%d ",a[x++][y--]);  /*x++和y--即可实现向左下扫描。注意自增特
											点。该处相当于a[x][y],x++,y++。用后自增的
											原因是,让扫描到奇数行时,xy值已经对应了
											该行的第一个。如果用前自增,当扫描到奇数行时,
											xy值仍对应的是上一行的末尾。*/
            }
            printf("%d ",a[x++][y]); //到边界后向下移动
        }
        else    //若i&1==0,则i为偶数。偶数行的扫描方向为右上。
        {
            for(j=0;j<i;j++)    //扫描第i行时向右上移动的次数为i
            {
                printf("%d ",a[x--][y++]);  //x--和y++即可实现向右上扫描
            }
            printf("%d ",a[x][y++]);    //到边界后向右移动
        }
    }
    //这时已经扫描完了所有长度递增的行,最近一次扫描要么是左下角,要么是右上角
    if(n&1) /*若n为奇数,则最近一次扫描是右上角,注意,最近一次扫描的是第n-1斜行,
            扫描后,还有一个y++,也就是说,这时(y,x)的位置是右上角的右方*/
    {
        y--;/*回到右上角*/x++;//向下移动
    }
    else    /*若n为偶数,则最近一次扫描是左下角,注意,最近一次扫描的是第n-1斜行,
            扫描后,还有一个x++,也就是说,这时(y,x)的位置是左下角的下方*/
    {
        x--;/*回到左下角*/y++;//向右移动
    }
    for(i=n-2;i>=0;i--) /*此时i代表长度递减的行序数,从n-2开始,使其与扫描时移动的次数
                        (也就是行的长度)相等,从第n-2行到第0行,共n-1行*/
    {
        if(i&1)
        {
            for(j=0;j<i;j++)
            {
                printf("%d ",a[x++][y--]);
            }
            printf("%d ",a[x][y++]);    //此时到边界后向右移动
        }
        else
        {
            for(j=0;j<i;j++)
            {
                printf("%d ",a[x--][y++]);
            }
            printf("%d ",a[x++][y]);    //此时到边界后向下移动
        }
    }

    return 0;
}

输出说明
在一行上输出Z字形扫描得到的整数序列,整数之间用空格分隔

输入样例
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

  • 4
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值