又看到一个比较有意思的题目,题目要求打印N*N螺旋方阵,比如5*5的方阵:
1 16 15 14 13
2 17 24 23 12
3 18 25 22 11
4 19 20 21 10
5 6 7 8 9
这个题目乍一看没有什么思路,和平常的二维数组打印不太一样。所以不能按照平常的思考方式去想这道题是不对的。
我们顺着题目的意思去思考,既然它的结果是螺旋的,那我们初始化数组的时候也螺旋初始化即可,可以发现数组是先从左边从上到下递增,再从最下面从左到右递增,再从下到上递增,再从右到左递增。我们把这称为一圈,一圈结束后再来一圈,不断循环。当然,循环不可能一直进行,循环结束的条件就是左边的列号大于右边的行号了,也就是已经初始化完成,已经走不了一圈了。
以5*5方阵举例子:
以5*5方阵举例子:
(1) 从上至下写左边一列(1,2,3,4,5),
从左至右写下边一行(6,7,8,9),
从下至上写右边一列(10,11,12,13)
从右至左写上边一行(14,15,16), 这样就写完一圈
(2) 继续写第二圈:
从上至下写左边一列(12,18,19),
从左至右写下边一行(20,21),
从下至上写右边一列(22,23)
从右至左写上边一行(24)
(3) 写最后一圈 (25)
从上面可以看到,写的过程总是一圈一圈地写。显然这要用循环结构, 每次循环做的事
是写一圈: 左边一列, 下边一行, 右边一列, 上边一行。这就是循环体。同时, 每次写一圈, 左边列号, 下边行号, 右边列号, 上边行号是不同的,是变化的, 因此要分别用 4 个变量来表示: left(左边列号), down(下边行号), right(右边列号), upper(上边行号). 而且有: 每循环一次, left 加 1, down 减 1, right 减 1, upper加 1。
那么要输出N*N的螺旋方阵,我们就得初始化left=upper=0,right=down=N-1(数组下标要-1)
干出来伪代码:
while (左边列号 left<=右边列号 right)
{
从上至下写左边一列; 左列号加 1;
从左至右写下边一行; 下行号减 1;
从下至上写右边一列; 右列号减 1;
从右至左写上边一行; 上行号加 1;
}
再写成代码,代码如下:
#define _CRT_SECURE_NO_WARNINGS 1
#define N 8
#include <stdio.h>
int main()
{
int left = 0;
int upper = 0;
int down = N-1;
int right = N-1;
int arr[50][50] = { 0 };
int i = 1;
int j = 0;
while (left <= right)
{
for (j = upper; j <= down; j++)
{
arr[j][left] = i++;
}
left++;
for (j = left; j <= right; j++)
{
arr[down][j] = i++;
}
down--;
for (j = down; j >= upper; j--)
{
arr[j][right] = i++;
}
right--;
for (j = right; j >= left; j--)
{
arr[upper][j] = i++;
}
upper++;
}
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
printf("%2d ",arr[i][j]);
}
printf("\n");
}
return 0;
}
注意这里用define定义常量即可一劳永逸,想输出几*几就输出几*几的,其次为了美观(方阵元素为一位数和两位数时)printf的输出域宽为2。
下面给出N为8时候的运行结果
nono了,今天的学习到此结束