免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: baozhao
打印 上一主题 下一主题

趣味编程 - 矩阵生成 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2011-01-27 13:59 |只看该作者
唉,老了

论坛徽章:
1
CU十二周年纪念徽章
日期:2013-10-24 15:41:34
12 [报告]
发表于 2011-01-27 14:07 |只看该作者
反向螺旋矩阵

论坛徽章:
0
13 [报告]
发表于 2011-01-27 14:14 |只看该作者
{:3_183:} 以为是做3D运算的呢...

论坛徽章:
1
摩羯座
日期:2013-11-14 15:56:09
14 [报告]
发表于 2011-01-27 21:53 |只看该作者
我还以为横、竖、斜向相加相等呢。

论坛徽章:
0
15 [报告]
发表于 2011-01-28 00:12 |只看该作者
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <errno.h>

  6. #define GET_XY(x,y,n)   ((y)*(n)+(x))

  7. char *Cmd;

  8. struct mm
  9. {
  10.     int x;
  11.     int y;
  12. } Mm[4] = { { 0, -1 }, { 1, 0 }, { 0, 1 }, { -1, 0 } };

  13. void
  14. rotate_mm( int r )
  15. {
  16.     struct mm m;

  17.     r %= 4;
  18.     if( r == 1 )
  19.     {
  20.         m = Mm[0];
  21.         Mm[0] = Mm[1];
  22.         Mm[1] = Mm[2];
  23.         Mm[2] = Mm[3];
  24.         Mm[3] = m;
  25.     }
  26.     else if( r == 2 )
  27.     {
  28.         m = Mm[0];
  29.         Mm[0] = Mm[2];
  30.         Mm[2] = m;
  31.         m = Mm[1];
  32.         Mm[1] = Mm[3];
  33.         Mm[3] = m;
  34.     }
  35.     else if( r == 3 )
  36.     {
  37.         m = Mm[0];
  38.         Mm[0] = Mm[3];
  39.         Mm[3] = Mm[2];
  40.         Mm[2] = Mm[1];
  41.         Mm[1] = m;
  42.     }

  43.     return;
  44. }

  45. int *
  46. make_matrix( int n )
  47. {
  48.     int *im;
  49.     int i;
  50.     int x, y;
  51.     int m;
  52.     int d, l;

  53.     if( ( n - 1 ) % 2 )
  54.     {
  55.         fprintf( stderr, "[%d] is not odd!\n", n );
  56.         return( (int *) NULL );
  57.     }

  58.     if( ( im = (int *) malloc( n*n*sizeof(int) ) ) == (int *) NULL )
  59.     {
  60.         fprintf( stderr, "malloc error: %s\n", strerror(errno) );
  61.         return( (int *) NULL );
  62.     }

  63.     x = y = n / 2;
  64.     m = 0;
  65.     d = 0;
  66.     l = 1;

  67.     for( i = 1; i <= n*n; i++ )
  68.     {
  69.         im[GET_XY(x,y,n)] = i;
  70.         x += Mm[m].x;
  71.         y += Mm[m].y;
  72.         if( ++d == l )
  73.         {
  74.             if( m % 2 )
  75.                 l++;
  76.             m = ( m + 1 ) % 4;
  77.             d = 0;
  78.         }
  79.     }

  80.     return( im );
  81. }

  82. int
  83. get_digits( int n )
  84. {
  85.     if( n / 10 )
  86.         return( get_digits( n / 10 ) + 1 );
  87.     else
  88.         return( 1 );
  89. }

  90. static void
  91. prt_help()
  92. {
  93.     fprintf( stderr, "Usage:%s [-r type] [-h] num\n", Cmd );

  94.     return;
  95. }

  96. int
  97. main( int ac, char **av )
  98. {
  99.     int c;
  100.     int errflag = 0;
  101.     int r = 0;
  102.     int *im;
  103.     int n;
  104.     int d;
  105.     int i;

  106.     if( ( Cmd = strrchr( av[0], '/' ) ) == NULL )
  107.         Cmd = av[0];
  108.     else
  109.         Cmd++;

  110.     while( ( c = getopt( ac, av, ":hr:" ) ) != -1 )
  111.     {
  112.         switch( c )
  113.         {
  114.             case 'r':
  115.                 r = atoi(optarg);
  116.                 if( r < 1 || r > 3 )
  117.                 {
  118.                     fprintf( stderr, "%s: type in 1,3\n", Cmd );
  119.                     errflag++;
  120.                 }
  121.                 break;
  122.             case 'h':
  123.                 errflag++;
  124.                 break;
  125.             case ':':        /* argument for option is missing */
  126.                 errflag++;
  127.                 fprintf( stderr, "%s: option -%c need argument\n",
  128.                                 Cmd, optopt );
  129.                 break;
  130.             case '?':        /* option is not in option set */
  131.                 errflag++;
  132.                 fprintf( stderr, "%s: option -%c is unknown \n",
  133.                                 Cmd, optopt);
  134.         }
  135.     }

  136.     if( errflag )
  137.     {
  138.         prt_help( );
  139.         exit( 1 );
  140.     }

  141.     if( optind != ac - 1 )
  142.     {
  143.         prt_help( );
  144.         exit( 1 );
  145.     }

  146.     n = atoi(av[optind]);

  147.     if( r )
  148.         rotate_mm( r );

  149.     if( ( im = make_matrix( n ) ) == (int *) NULL )
  150.     {
  151.         fprintf( stderr, "%s: make_matrix error!\n", Cmd );
  152.         exit( 1 );
  153.     }

  154.     d = get_digits( n * n );

  155.     printf( "%d\n", n );
  156.     for( i = 0; i < n*n; i++ )
  157.     {
  158.         printf( "%-*d ", d, *im++ );
  159.         if( i % n == n - 1 )
  160.             printf( "\n" );
  161.     }
  162.     printf( "\nIt's OK\n" );

  163.     free( im - n * n );

  164.     return( 0 );
  165. }
复制代码
用以前的程序架构完成的,算法部分其实很简单,人是怎么想的,程序就怎么跑

论坛徽章:
0
16 [报告]
发表于 2011-01-28 13:44 |只看该作者
回复 3# baozhao

其实都一样,是一圈圈往里过渡的,主要是定位i行j列实在第几圈,就像程序里头的c值,然后就是定位在圈中的什么位置,对应输出即可,主要是怎么省空间

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:49:45
17 [报告]
发表于 2011-01-28 14:53 |只看该作者
本帖最后由 koolcoy 于 2011-01-28 14:54 编辑

换一种想法,这个题目特别简单,当然前提时O(n^2)的空间复杂度可以接受

  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. enum Direction {
  4.         DOWN, RIGHT, UP, LEFT
  5. };

  6. void getNextCell(int side, int* matrix, int& x, int& y, Direction& direction) {
  7.         switch (direction) {
  8.         case DOWN:
  9.                 if (y < side - 1 && matrix[side * (y + 1) + x] == 0) {
  10.                         ++y;
  11.                 } else {
  12.                         direction = RIGHT;
  13.                         ++x;
  14.                 }
  15.                 break;
  16.         case RIGHT:
  17.                 if (x < side - 1 && matrix[side * y + x + 1] == 0) {
  18.                         ++x;
  19.                 } else {
  20.                         direction = UP;
  21.                         --y;
  22.                 }
  23.                 break;
  24.         case UP:
  25.                 if (y > 0 && matrix[side * (y - 1) + x] == 0) {
  26.                         --y;
  27.                 } else {
  28.                         direction = LEFT;
  29.                         --x;
  30.                 }
  31.                 break;
  32.         case LEFT:
  33.                 if (x > 0 && matrix[side * y + x - 1] == 0) {
  34.                         --x;
  35.                 } else {
  36.                         direction = DOWN;
  37.                         ++y;
  38.                 }
  39.                 break;
  40.         }
  41. }

  42. int main(int argc, char** argv) {
  43.         int side = 0;
  44.         if (argc != 2 || sscanf(argv[1], "%d", &side) != 1
  45.                         || side % 2 != 1 || side <= 0) {
  46.                 printf("Invalid input\n");
  47.                 return 1;
  48.         }
  49.         int matrixSize = side * side;

  50.         int* matrix = (int*)calloc(sizeof(int) * matrixSize, 1);

  51.         int x = 0;
  52.         int y = 0;
  53.         int value = matrixSize;
  54.         Direction direction = DOWN;
  55.         do {
  56.                 matrix[y * side + x] = value;
  57.                 --value;
  58.                 getNextCell(side, matrix, x, y, direction);
  59.         } while (!(x == side / 2 && y == side / 2));

  60.         matrix[y * side + x] = 1;

  61.         for (int i = 0; i < side; ++i) {
  62.                 for (int j = 0; j < side; ++j) {
  63.                         printf("%4d ", matrix[i * side + j]);
  64.                 }
  65.                 printf("\n");
  66.         }

  67.         return 0;
  68. }
复制代码

论坛徽章:
0
18 [报告]
发表于 2011-01-29 11:58 |只看该作者
呵呵,螺旋矩阵的问题,哥好多年以前也玩过。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP