`
seara
  • 浏览: 648715 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

生成n*n蛇形矩阵的算法

阅读更多
本文为原创,如需转载,请注明作者和出处,谢谢!

在描述算法之前,先看看下面的5*5的表格:

1 3 4 10 11
2 5 9 12
19
6 8 13 18 20
7 14 17 21 24
15 16 22 23 25

上面的表格很容易看出规律。就是从左上角第一个格开始(起始为1),然后延右上角到左下角的斜线。先从下到上,再从上到下。开始按数字递增排列。也就是说每一个斜线上分别有如下几组数字:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

由于是先从上到下(1可以看做是从上到下),再从下到上,很象一条蛇,因此,该数字表格也可称为蛇形矩阵。现在要与一个方法(或函数),方法的参数是一个int类型,表示n,方法返回一个二维数组,表示要获得的往返接力数字表格。
实际上,这个算法并不复杂,只需要从分别获得1至n^2中每个数字对应的二维数组的坐标就可以了。先拿这个5行5列的表格来说,求出上面每组数组对应的坐标(起始位置为0)。

第0组
第1组
第2组
第3组
第4组
第5组
第6组
第7组
第8组
1
2 3
4 5 6
7 8 9 10
11 12 13 14 15
16 17 18 19
20 21 22
23 24
25
(0,0)
(1,0) (0,1)
(0,2) (1,1) (2,0)
(3,0) (2,1) (1,2) (0,3)
(0,4) (1,3) (2,2) (3,1) (4,0)
(4,1) (3,2) (2,3) (1,4)
(2,4) (3,3) (4,2)
(4,3) (3,4)
(4,4)

从上面的从标可以看出一个规律。 左上角的半个表格(以对角线分界)的横坐标和纵坐标从0开始,每一组增1,直到增至表格的边界(n - 1),而且是交替的,也就是说,偶数行是列增,行减小,行+列=组的索引。而右下角的4组数字虽然行、列也是交替增长的,但递减的行或列总是从(n - 1)开始(对于本例,是从4开始),而递增的行或列总是从index - n + 1开始,其中index表示组的索引。这就可以得出一个算法。实现代码如下:
<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->publicstaticint[][]getGrid(intn)
{
int[][]array=newint[n][n];
introw=0,col=0,m=1;
//用于控制奇偶组,false表示偶组,true表示奇组
booleanisRow=false;
//i表示当前组的索引,从0开始
for(inti=0;i<(2*n-1);i++)
{
row
=i;
while(row>=((i<n)?0:i-n+1))
{
//如果处理的是右下角表格中的数字,行或列最大不能超过n-1
if(row>(n-1))
row
=n-1;
col
=i-row;
if(isRow)
array[row][col]
=m;
else//将row变成列,将col变成行
array[col][row]=m;
m
++;
row
--;
}
//切换奇偶组
isRow=!isRow;
}
returnarray;
}

另一种算法

上面实现的算法需要循环N*N次才可以生成蛇形矩阵。但仔细分析一下,还可以稍微变换一下这个算法,使循环次数减小至N*N/2。我们上学时曾学过用高斯的方法计算1+2+3+...+100, 1 + 100 = 101,2 + 99 = 101,...,50+51 = 101,因此,结果是101 * 50 = 5050。很方便。我们这个算法也可采用类似的方法。仔细观察上面5*5的数字表格发现,算出左上角的矩阵中每一个数字后,都可以直接获得右下角度某个位置的数字。例如在(0,0)位置的1,可以向到(4,4)位置的25,(1,2)位置的9可以得到(3,2)位置的17。我们发现,每一对数之和都为26。而且它们坐标的关系是(row,col),(n - row - 1, n - col - 1)。因此,只要得到左上角的半个矩阵,就可以得出右下角的另外半个矩阵。如果n为奇数,对角线中间的一个数(在5*5的矩阵中是13)与之对应的数是其自身。好,我们看看改进的算法的实现:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->publicstaticint[][]getGrid1(intn)
{
int[][]array=newint[n][n];
introw=0,col=0,m=1;
intnumber1=(n*n/2+n*n%2);
intnumber2=n*n+1;
booleanisRow=false;
//number1表示要计算的蛇形矩阵中最大的数字,对于5*5矩阵来说该数是13
for(inti=0;m<number1;i++)
{
row
=i;
while(row>=0)
{
col
=i-row;
if(isRow)
{
array[row][col]
=m;
//填充与m对应的另外一个数
array[n-row-1][n-col-1]=number2-m;
}
else
{
array[col][row]
=m;
//填充与m对应的另外一个数
array[n-col-1][n-row-1]=number2-m;

}
m
++;
if(m>=number1)break;
row--;
}
isRow
=!isRow;
}
returnarray;
}

上面的算法虽然将循环次数减少了一半,但每次循环的计算量增加了,因此,算法总体效率并没有提高。至于使用哪个算法,可根据实际情况决定。
如果想输出n=10的数字表格,可以使用int[][] grid = getGrid(10)或int[][] grid1 = getGrid1(10),会得到同样的结果。输出grid和grid1,看看是不是下面的结果:

1 3 4 10 11 21 22 36 37 55
2 5 9 12 20 23 35 38 54 56
6 8 13 19 24 34 39 53 57 72
7 14 18 25 33 40 52 58 71 73
15 17 26 32 41 51 59 70 74 85
16 27 31 42 50 60 69 75 84 86
28 30 43 49 61 68 76 83 87 94
29 44 48 62 67 77 82 88 93 95
45 47 63 66 78 81 89 92 96 99
46 64 65 79 80 90 91 97 98 100

哪位还有更好的算法,请跟贴。可以使用任何语言实现。


国内最棒的Google Android技术社区(eoeandroid),欢迎访问!

《银河系列原创教程》发布

《Java Web开发速学宝典》出版,欢迎定购

分享到:
评论

相关推荐

    螺旋蛇形矩阵

    总的来说,生成螺旋蛇形矩阵的算法是一种经典的编程问题,它可以锻炼对二维数组操作的理解和边界条件的处理。通过阅读和理解`rect_num.CPP`中的代码,你可以进一步了解这种数据结构的实现细节,并学习如何在实际编程...

    c语言编写n阶蛇形方阵

    本篇文章将深入探讨如何使用C语言来生成一个n阶的蛇形方阵,即元素按蛇形路径排列的正方形矩阵,并对代码进行详细的解析。 #### 蛇形方阵的概念 蛇形方阵是指一个n×n的矩阵,其中的元素按照蛇形路径依次填充,即...

    经典的C语言算法实例

    - **问题描述**:生成一个包含对角线元素的矩阵。 - **算法思路**:利用循环结构输出主对角线和副对角线上的元素。 ##### 2.6 魔方阵 - **问题描述**:生成一个具有特殊性质的魔方阵(每行、每列和两条对角线上的...

    acm编程比赛入门题目集.doc

    生成蛇形矩阵可以通过双指针方法实现,两个指针分别代表当前行和列,交替增加行和列,直到填满矩阵。在输出时,注意每行末尾不要多余的空格,相邻数字之间用一个空格分隔。 4. **青蛙的约会**: 这是一个数学概率...

    第三届全国软件专业人才设计与创业大赛”

    - **题目描述**: 给定一个N×N的矩阵,要求编程实现蛇形填数。 - **输入**: 矩阵大小N。 - **输出**: 按照蛇形顺序填充数字的矩阵。 - **关键知识点**: - 使用二维数组表示矩阵。 - 控制变量用于追踪当前填充的...

    C++经典编程题目 经典考试题目

    要生成所有可能的N阶拉丁方阵,程序需要遍历所有可能的数字组合,确保每一行每一列的数字都是唯一的。这个过程可能需要递归或者深度优先搜索(DFS)。 5. **数制转换**:将十进制数转换为N进制数,需要理解不同进制...

    C入门76题

    1. **生成拉丁方阵:** 使用递归算法或回溯算法生成拉丁方阵。 2. **验证拉丁方阵:** 检查每行和每列是否符合拉丁方阵的要求。 3. **统计个数:** 在生成过程中记录符合条件的拉丁方阵的数量。 ### 知识点五:十...

    C++经典编程题、、、、

    2. **回溯算法:**使用回溯算法生成所有可能的排列。 3. **条件判断:**在回溯过程中检查相邻数字之和是否为素数。 #### 题目12:迷宫寻路 **知识点概述:** 本题是一个经典的路径搜索问题,涉及到图的遍历算法,...

    c语言竞赛习题

    * 输入一个 n*n 字符矩阵,把它左转 90 度后输出 知识点: * 数组处理:处理二维数组,进行旋转操作 6. 进制转换 1: * 输入基数 b(2)和正整数 n(十进制),输出 n 的 b 进制表示 知识点: * 数学计算:...

    ACM所有试题

    1. **矩阵的生成:** 需要按照特定规则生成一个上三角形的矩阵。 2. **嵌套循环:** 使用两个嵌套循环来填充矩阵的各个元素。 3. **行列控制:** 控制行和列的顺序,确保按蛇形路径正确填充矩阵。 4. **输出格式:**...

    2018暨大上机真题1

    以上就是针对题目中四个部分的知识点详解,包括斐波那契数列的递归实现、蛇形矩阵的生成、偶数拆分为素数和的方法以及最大子序列和问题的解决方案。这些知识点涵盖了基础的算法和数据结构,对于学习和理解计算机编程...

    acm编程比赛入门题目集.pdf

    需要编写程序生成一个蛇形矩阵,并输出对应的矩阵数据。 四、青蛙的约会 问题描述:两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面。它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝...

    76道高难度CC编程题.pdf

    当给出N*N的矩阵,要求用程序填入下列形式的数:倒填、蛇形填数、回转填数。 知识点: * 数组:使用C++的数组来存储矩阵的数据。 * 循环语句:使用C++的for循环来填充矩阵。 题目7:文本处理 读入一行文本,包含...

    第三届全国软件专业人才设计与创业大赛”校内选拔赛机试比赛(最终).docx

    4. **题目示例**:比赛包含五道题目,分别涉及矩阵的蛇形填数、求幂的最后三位数、判断日期对应的“打鱼”或“晒网”状态、最大切割长度计算和特定条件的字符串生成。例如,第一题要求编程实现N*N矩阵的蛇形填数;第...

    C语言初学者必做题.doc

    6. **矩阵填充算法**: 这些题目展示了不同的矩阵填充方式,包括倒序、蛇形和回转填充。每种填充方式都需要特定的算法,如倒序填充只需简单地从后往前填充;蛇形填充需要交替方向填充,可能需要两个指针或变量来...

Global site tag (gtag.js) - Google Analytics