本文为原创,如需转载,请注明作者和出处,谢谢!
在描述算法之前,先看看下面的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阶的蛇形方阵,即元素按蛇形路径排列的正方形矩阵,并对代码进行详细的解析。 #### 蛇形方阵的概念 蛇形方阵是指一个n×n的矩阵,其中的元素按照蛇形路径依次填充,即...
- **问题描述**:生成一个包含对角线元素的矩阵。 - **算法思路**:利用循环结构输出主对角线和副对角线上的元素。 ##### 2.6 魔方阵 - **问题描述**:生成一个具有特殊性质的魔方阵(每行、每列和两条对角线上的...
生成蛇形矩阵可以通过双指针方法实现,两个指针分别代表当前行和列,交替增加行和列,直到填满矩阵。在输出时,注意每行末尾不要多余的空格,相邻数字之间用一个空格分隔。 4. **青蛙的约会**: 这是一个数学概率...
- **题目描述**: 给定一个N×N的矩阵,要求编程实现蛇形填数。 - **输入**: 矩阵大小N。 - **输出**: 按照蛇形顺序填充数字的矩阵。 - **关键知识点**: - 使用二维数组表示矩阵。 - 控制变量用于追踪当前填充的...
要生成所有可能的N阶拉丁方阵,程序需要遍历所有可能的数字组合,确保每一行每一列的数字都是唯一的。这个过程可能需要递归或者深度优先搜索(DFS)。 5. **数制转换**:将十进制数转换为N进制数,需要理解不同进制...
1. **生成拉丁方阵:** 使用递归算法或回溯算法生成拉丁方阵。 2. **验证拉丁方阵:** 检查每行和每列是否符合拉丁方阵的要求。 3. **统计个数:** 在生成过程中记录符合条件的拉丁方阵的数量。 ### 知识点五:十...
2. **回溯算法:**使用回溯算法生成所有可能的排列。 3. **条件判断:**在回溯过程中检查相邻数字之和是否为素数。 #### 题目12:迷宫寻路 **知识点概述:** 本题是一个经典的路径搜索问题,涉及到图的遍历算法,...
* 输入一个 n*n 字符矩阵,把它左转 90 度后输出 知识点: * 数组处理:处理二维数组,进行旋转操作 6. 进制转换 1: * 输入基数 b(2)和正整数 n(十进制),输出 n 的 b 进制表示 知识点: * 数学计算:...
1. **矩阵的生成:** 需要按照特定规则生成一个上三角形的矩阵。 2. **嵌套循环:** 使用两个嵌套循环来填充矩阵的各个元素。 3. **行列控制:** 控制行和列的顺序,确保按蛇形路径正确填充矩阵。 4. **输出格式:**...
以上就是针对题目中四个部分的知识点详解,包括斐波那契数列的递归实现、蛇形矩阵的生成、偶数拆分为素数和的方法以及最大子序列和问题的解决方案。这些知识点涵盖了基础的算法和数据结构,对于学习和理解计算机编程...
需要编写程序生成一个蛇形矩阵,并输出对应的矩阵数据。 四、青蛙的约会 问题描述:两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面。它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝...
当给出N*N的矩阵,要求用程序填入下列形式的数:倒填、蛇形填数、回转填数。 知识点: * 数组:使用C++的数组来存储矩阵的数据。 * 循环语句:使用C++的for循环来填充矩阵。 题目7:文本处理 读入一行文本,包含...
4. **题目示例**:比赛包含五道题目,分别涉及矩阵的蛇形填数、求幂的最后三位数、判断日期对应的“打鱼”或“晒网”状态、最大切割长度计算和特定条件的字符串生成。例如,第一题要求编程实现N*N矩阵的蛇形填数;第...
6. **矩阵填充算法**: 这些题目展示了不同的矩阵填充方式,包括倒序、蛇形和回转填充。每种填充方式都需要特定的算法,如倒序填充只需简单地从后往前填充;蛇形填充需要交替方向填充,可能需要两个指针或变量来...