Chinaunix首页 | 论坛 | 博客
  • 博客访问: 144988
  • 博文数量: 43
  • 博客积分: 264
  • 博客等级: 二等列兵
  • 技术积分: 320
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-25 08:46
文章分类

全部博文(43)

文章存档

2015年(4)

2014年(1)

2012年(38)

分类:

2012-06-04 10:00:17

原文地址:螺旋矩阵的C实现 作者:Heartwork

之前听同事提过的面试有这样的题目,感觉挺好玩,就也写了一个出来。

    一般的思路是按照螺旋的路径把数字填好到对应的二维数组中,最后打印出来,其实完全可以在获知矩阵大小后计算出每一个位置对应的数字。这种解法的好处是更灵活,而且免去了使用二维数组,简化了代码。

运行效果:
$ ./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


代码如下:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <math.h>

  4. // static就可以了,编译时使用-O2就可以内联展开。
  5. static int calculate(int n, int i, int j);

  6. int main(int argc, char *argv[])
  7. {
  8.     int n, i, j;

  9.     if (argc < 2) {
  10.         return 0;
  11.     }

  12.     n = atoi(argv[1]);

  13.     for (i = 0; i < n; ++i) {
  14.         for (j = 0; j < n; ++j) {
  15.             printf("%2d ", calculate(n - 1, i, j));
  16.         }
  17.         printf("\n");
  18.     }

  19.     return ;
  20. }

  21. // calculate用来计算边长为n+1的矩阵(i, j)位置上的数值
  22. static int calculate(int n, int i, int j)
  23. {
  24.     // (i, j)位置的数值
  25.     int k = 0;
  26.     // 用来计算(i, j)的外有几个完整的“圈”
  27.     int mini = i < n - i ? i : n - i;
  28.     int minj = j < n - j ? j : n - j;
  29.     int min = mini < minj ? mini : minj;
  30.     int h;

  31.     // h用来控制层数
  32.     for (h = 0; h < min; ++h) {
  33.         // 内层的圈要比临近外层的圈的边长小2
  34.         k += (n - 2 * h) * 4;
  35.     }

  36.     // (i, j)位于同层的上方
  37.     if (i == min) {
  38.         // 直接取得j坐标的位置,注意需要减掉min,因为外围已经计算过了
  39.         k += j - min + 1;
  40.     }
  41.     // (i, j)位于同层的右侧
  42.     else if (j == n - min) {
  43.         // 需要加上上方边长的长度
  44.         k += (n - 2 * min) + (i - min) + 1;
  45.     }
  46.     // (i, j)位于同层的下方
  47.     else if (i == n - min) {
  48.         // 需要加上上方和右侧的长度
  49.         k += (n - 2 * min) * 2 + (n - min - j) + 1;
  50.     }
  51.     // (i, j)位于同层的左侧
  52.     else if (j == min) {
  53.         // 需要加上上方、右侧和下方的长度
  54.         k += (n - 2 * min) * 3 + (n - min - i) + 1;
  55.     }

  56.     return k;
  57. }
阅读(686) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~