之前听同事提过的面试有这样的题目,感觉挺好玩,就也写了一个出来。
一般的思路是按照螺旋的路径把数字填好到对应的二维数组中,最后打印出来,其实完全可以在获知矩阵大小后计算出每一个位置对应的数字。这种解法的好处是更灵活,而且免去了使用二维数组,简化了代码。
运行效果:
$ ./a.out 3
1 2 3
8 9 4
7 6 5
$ ./a.out 4
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
代码如下:
- #include <stdio.h>
-
#include <stdlib.h>
-
#include <math.h>
-
-
// static就可以了,编译时使用-O2就可以内联展开。
-
static int calculate(int n, int i, int j);
-
-
int main(int argc, char *argv[])
-
{
-
int n, i, j;
-
-
if (argc < 2) {
-
return 0;
-
}
-
-
n = atoi(argv[1]);
-
-
for (i = 0; i < n; ++i) {
-
for (j = 0; j < n; ++j) {
-
printf("%2d ", calculate(n - 1, i, j));
-
}
-
printf("\n");
-
}
-
-
return ;
-
}
-
-
// calculate用来计算边长为n+1的矩阵(i, j)位置上的数值
-
static int calculate(int n, int i, int j)
-
{
-
// (i, j)位置的数值
-
int k = 0;
-
// 用来计算(i, j)的外有几个完整的“圈”
-
int mini = i < n - i ? i : n - i;
-
int minj = j < n - j ? j : n - j;
-
int min = mini < minj ? mini : minj;
-
int h;
-
-
// h用来控制层数
-
for (h = 0; h < min; ++h) {
-
// 内层的圈要比临近外层的圈的边长小2
-
k += (n - 2 * h) * 4;
-
}
-
-
// (i, j)位于同层的上方
-
if (i == min) {
-
// 直接取得j坐标的位置,注意需要减掉min,因为外围已经计算过了
-
k += j - min + 1;
-
}
-
// (i, j)位于同层的右侧
-
else if (j == n - min) {
-
// 需要加上上方边长的长度
-
k += (n - 2 * min) + (i - min) + 1;
-
}
-
// (i, j)位于同层的下方
-
else if (i == n - min) {
-
// 需要加上上方和右侧的长度
-
k += (n - 2 * min) * 2 + (n - min - j) + 1;
-
}
-
// (i, j)位于同层的左侧
-
else if (j == min) {
-
// 需要加上上方、右侧和下方的长度
-
k += (n - 2 * min) * 3 + (n - min - i) + 1;
-
}
-
-
return k;
-
}
阅读(12075) | 评论(1) | 转发(2) |