/**
 * 描述:打印zigzag矩阵
 *       0  1  5  6 14 15 27 28
 *       2  4  7 13 16 26 29 42
 *       3  8 12 17 25 30 41 43
 *       9 11 18 24 31 40 44 53
 *      10 19 23 32 39 45 52 54
 *      20 22 33 38 46 51 55 60
 *      21 34 37 47 50 56 59 61
 *      35 36 48 49 57 58 62 63
 * 
 * Date: 2011-08-08
 */

#include <iostream>
#include <iomanip>
using namespace std;

int a[10][10];

void PrintZigzag(int n)
{
    int value = 0;
    int i,j,k;
    int num;
    //上三角
    for (i=0; i<n; i++)
    {
        num = 0;
        if (0 == i % 2)
        {/*偶数*/
            j = i;
            k = 0;
            while (num++ <= i)
            {
                a[j--][k++] = value++;    
            }
        }
        else
        {/*奇数*/
            j = 0;
            k = i;
            while (num++ <= i)
            {
                a[j++][k--] = value++;    
            }    
        }
    }

//下三角
    for (i = n-2; i >= 0; i--)
    {
        num = 0;
        if (0 == i % 2)
        {/*偶数*/
            j = n - 1;
            k = n -1 - i;
            while (num++ <= i)
            {
                a[j--][k++] = value++;    
            }
        }
        else
        {/*奇数*/
            j = n - 1 - i;
            k = n - 1;
            while (num++ <= i)
            {
                a[j++][k--] = value++;    
            }    
        }
    }

}

/**
 * test
 */
int main()
{
    int n, i, j;
    cin >> n;
    for(i = 0; i < n; i++)
    {
        for (j = 0; j < n; j++)
        {
            a[i][j] = 0;
        }
    }

PrintZigzag(n);

for(i = 0; i < n; i++)
    {
        for (j = 0; j < n; j++)
        {
            cout << setw(4) << a[i][j];
        }
        cout << endl;
    }

return 1;
}

方法虽蠢却易理解。
通过观察zigzag矩阵可发现几个特点:
  1. 左上三角(以对角线方向查看)个数从1递增至n(矩阵维数),右下三角从n-1递减至1。则可以将zigzag矩阵分为上三角和下三角两部分处理。
  2. 观察zigzag矩阵,以对角线方向计(行数从0开始计数),则偶数行规律是:从左到右;奇数行规律是:从右到左。则再分为奇偶行进行处理。

当然,有一种十分巧妙的方法如下。
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int N;
    int s, i, j;
    int squa;
    scanf("%d", &N);
    /* 分配空间 */
    int **a = (int **)malloc(N * sizeof(int *));
    if(a == NULL)
        return 0;
    for(i = 0; i < N; i++) 
    {
        if((a[i] = (int *)malloc(N * sizeof(int))) == NULL) 
        {
            while(--i>=0)
                free(a[i]);
            free(a);
            return 0;
        }
    }
    /* 数组赋值 */
    squa = N*N;    
    for(i = 0; i < N; i++)
        for(j = 0; j < N; j++) 
        {
            s = i + j;
            if(s < N) /*上三角*/
            {
                a[i][j] = s*(s+1)/2 + (((i+j)%2 == 0)? j : i);
            }
            else 
            { /*下三角*/
                s = (N-1-i) + (N-1-j);
                a[i][j] = squa - s*(s+1)/2 - (N - (((i+j)%2 == 0)? j : i));
            }
        }
    /* 打印输出 */    
    for(i = 0; i < N; i++) 
    {
        for(j = 0; j < N; j++)
        {
            printf("%6d", a[i][j]);
        }
        printf("\n");
    }
    return 1;
}

通过观察zigzag数组,可以发现,对角线上(i+j)为常数,记为s(s=i+j)。(i为行数,j为列数)
仍然是分为上三角和下三角两部分处理。
对于上三角,每一个斜线上的个数比上一行多一个。且,每个斜线上的第一个元素表示了该斜线之前元素的个数。运用等差数列求和公式,则每一斜线第一个元素的值为 (1 + (i+j)) * (i+j) / 2 = (1 + s) * s / 2
斜线中的任意元素可表示为s*(s+1)/2+i(此处来个奇偶判断就知道是加i还是加j了。)那么就不难理解代码中 a[i][j] = s*(s+1)/2 + (((i+j)%2 == 0)? j : i);的含义了。
对于下三角,斜线上元素的个数是递减的。反过来看可以看成是递增的,就仍然可以套用等差数列求和公式,求出剩下的元素的个数,用总元素个数减去剩下的元素个数就是当前斜线上的第一个元素值。

我们知道所有元素的个数是n*n,则该斜线的第一个元素值为n*n - s*(s+1)/2。此处的s就不是i+j了,而是(n-1-i)+(n-1-j)。这样也不难理解代码中s = (N-1-i) + (N-1-j);  a[i][j] = squa - s*(s+1)/2 - (N - (((i+j)%2 == 0)? j : i));两句的含义了。

转自:http://blog.163.com/yangjun1988422@126/blog/static/4741291720117842634276/

打印zigtag矩阵相关推荐

  1. Python实现打印螺旋矩阵功能的方法

    Python实现打印螺旋矩阵功能的方法 本文实例讲述了Python实现打印螺旋矩阵功能的方法.分享给大家供大家参考,具体如下: 一.问题描述 输入N, 打印 N*N 螺旋矩阵 比如 N = 3,打印: ...

  2. Java黑皮书课后题第8章:**8.14(探讨矩阵)编写程序,提示用户输入一个方阵的长度,随机地在矩阵中填入0和1,打印这个矩阵,然后找出整行、整列或者对角线都是1或0的行、列和对角线

    **8.14(探讨矩阵)编写程序,提示用户输入一个方阵的长度,随机地在矩阵中填入0和1,打印这个矩阵,然后找出整行.整列或者对角线都是1或0的行.列和对角线 题目 题目描述与运行示例 破题 代码 题目 ...

  3. Java黑皮书课后题第8章:*8.10(最大的行和列)编写一个程序,在一个4*4的矩阵中随机填入0和1,打印该矩阵,分别找到第一个具有最多1的行和列

    *8.10(最大的行和列)编写一个程序,在一个4*4的矩阵中随机填入0和1,打印该矩阵,分别找到第一个具有最多1的行和列 题目 题目描述与运行示例 破题 代码 题目 题目描述与运行示例 8.10(最大 ...

  4. 打印zigzag矩阵

    /** * 描述:打印zigzag矩阵 * 0 1 5 6 14 15 27 28 * 2 4 7 13 16 26 29 42 * 3 8 12 17 25 30 41 43 * 9 11 18 2 ...

  5. 使用numpy.sin()打印矢量/矩阵元素的正弦值 使用Python的线性代数

    Prerequisite: 先决条件: Defining a Vector 定义向量 Defining a Matrix 定义矩阵 Numpy is the library of function t ...

  6. 一种打印螺旋式矩阵的方法

    用户输入一个维度,打印从中心向外逆时针旋转的矩阵,左上角为最后一个数.例如输入5,输出为: 24 23 22 21 20 09 08 07 06 19 10 01 00 05 18 11 02 03 ...

  7. 蛇形矩阵 java_Java打印蛇形矩阵

    具体的题目名字忘记了,之前记得有个算法题目,根据给出的整数打印有规律的矩阵. 当n=3: 1 2 3 8 9 4 7 6 5 当n=4: 1 2 3 4 12 13 14 5 11 16 15 6 1 ...

  8. 使用numpy.tanh()打印矢量/矩阵元素的双曲正切值 使用Python的线性代数

    Prerequisite: 先决条件: Defining a Vector 定义向量 Defining a Matrix 定义矩阵 Numpy is the library of function t ...

  9. python螺旋输出矩阵_飘逸的python - 打印螺旋矩阵

    算法分析: 螺旋矩阵用二维数组表示,坐标(x,y),即(x轴坐标,y轴坐标) 顺时针螺旋的方向是->右,下,左,上,用数值表示即是x加1格(1,0),y加1格(0,1),x减1格(-1,0),y ...

最新文章

  1. Q-learning
  2. jquery判断页面滚动条(scroll)是上滚还是下滚,且是否滚动到头部或者底部
  3. Thread类和Runnable接口
  4. Windows Phone 7 自适应键盘输入
  5. Python面向对象编程三大特性之封装
  6. vue向ifarm传值_vue组件间传值
  7. 一键开启微信“开关头像”,快试试!
  8. Java Web 项目SSO实战二之(win7 and Windows server 2008)
  9. 黑马程序员 Python学习笔记之PyCharm 的初始设置
  10. 查看mysql默认端口号和修改端口号
  11. 色环在线计算机,多功能电子计算软件(eTools)
  12. 打砖块游戏源文件_2020年10月手游海外买量分析: 多款RPG游戏上新,休闲厂商霸占Top 推广榜...
  13. 基于野火霸道的 STM32F103 代码集合
  14. flashfxp配置文件服务器同步,如何导出FlashFXP的站点配置文件
  15. 【C++】数字的组合排列情况
  16. dlna投屏显示服务器没互动,Dlna投屏
  17. 按国家归类的海淘网站大全
  18. 用Python获取磁力种子
  19. 如何设计出优秀的EDM邮件营销模板
  20. 更改cognos upfront 的外观

热门文章

  1. ubuntu 18.04 netplan 配置多网卡、多路由、多ip
  2. 关于领域驱动设计(DDD)的理论知识
  3. java 新功能_最新的Java版本101有什么新功能?
  4. linux系统(Centos7)安装VScode笔记
  5. ubuntu 使用惠普HP打印机
  6. 简洁无广告的解压软件
  7. Linux管道命令grep 和 wc
  8. 软件安全课程实验2 Shellshock Attack lab
  9. 初识Java+JDK的安装与环境变量的配置+IDEA的安装
  10. java棒棒糖和皮卡丘八音盒_如何比别人抢先一步买到肯德基的皮卡丘八音盒?我有两个小建议...