user-0 提问: 求解释下这个代码的思路

回复:
user: user-1
content: KISS！ Don‘t Make Me Think! //n=1, //1 //n=2, //12 //34 //n=3, //126 //357 //489 //n=4, //  1  2  6  7 //  3  5  8 13 //  4  9 12 14 // 10 11 15 16 //n=5, //  1  2  6  7 15 //  3  5  8 14 16 //  4  9 13 17 22 // 10 12 18 21 23 // 11 19 20 24 25 //之字形 //模仿蚂蚁爬的过程 #include <stdio.h> #define MAXN 9 int m[MAXN][MAXN]; int i,x,y,dx,dy,n,n2,k; void main() {     for (i=1;i<=MAXN;i++) {         n2=i*i;         k=1;         if (n2>9) k=3;         x=0;         y=0;         dx=1;         dy=-1;         n=1;         m[y][x]=n;         while (1) {             if (n>=n2) break;             n++;             x=x+dx;             y=y+dy;             if (y>=i) {                 x=x+2;                 y=i-1;                 dx=1;                 dy=-1;             }             if (x>=i) {                 y=y+2;                 x=i-1;                 dx=-1;                 dy=1;             }             if (y<0) {                 y=0;                 dx=-1;                 dy=1;             }             if (x<0) {                 x=0;                 dx=1;                 dy=-1;             }             m[y][x]=n;         }         for (y=0;y<i;y++) {             for (x=0;x<i;x++) {                 printf("%*d",k,m[y][x]);             }             printf("\n");         }         printf("-------------%d--------------\n",i);     } } //1 //-------------1-------------- //12 //34 //-------------2-------------- //126 //357 //489 //-------------3-------------- //  1  2  6  7 //  3  5  8 13 //  4  9 12 14 // 10 11 15 16 //-------------4-------------- //  1  2  6  7 15 //  3  5  8 14 16 //  4  9 13 17 22 // 10 12 18 21 23 // 11 19 20 24 25 //-------------5-------------- //  1  2  6  7 15 16 //  3  5  8 14 17 26 //  4  9 13 18 25 27 // 10 12 19 24 28 33 // 11 20 23 29 32 34 // 21 22 30 31 35 36 //-------------6-------------- //  1  2  6  7 15 16 28 //  3  5  8 14 17 27 29 //  4  9 13 18 26 30 39 // 10 12 19 25 31 38 40 // 11 20 24 32 37 41 46 // 21 23 33 36 42 45 47 // 22 34 35 43 44 48 49 //-------------7-------------- //  1  2  6  7 15 16 28 29 //  3  5  8 14 17 27 30 43 //  4  9 13 18 26 31 42 44 // 10 12 19 25 32 41 45 54 // 11 20 24 33 40 46 53 55 // 21 23 34 39 47 52 56 61 // 22 35 38 48 51 57 60 62 // 36 37 49 50 58 59 63 64 //-------------8-------------- //  1  2  6  7 15 16 28 29 45 //  3  5  8 14 17 27 30 44 46 //  4  9 13 18 26 31 43 47 60 // 10 12 19 25 32 42 48 59 61 // 11 20 24 33 41 49 58 62 71 // 21 23 34 40 50 57 63 70 72 // 22 35 39 51 56 64 69 73 78 // 36 38 52 55 65 68 74 77 79 // 37 53 54 66 67 75 76 80 81 //-------------9--------------

user: user-2
content: 我稍微改了一下，调整了方向和楼主画的矩阵一致，取消了两重循环提高了效率。 #include <stdio.h>  #define M 50  void main() {     int i,j,n,count = 1;     int row_min, row_max;     int dada[M][M];     printf("Input n(0~%d):",M);     scanf("%d",&n);     if (n >= M) {         return;     }     for(i=1;i<=2*n-1;i++)    {         if (i <= n) {             row_min = 1;             row_max = i;         } else {             row_min = i - n + 1;             row_max = n;         }         if (i%2 == 0)         {             for (j=row_min;j<=row_max;j++)             {                 dada[j][i+1-j] = count++;             }         }         else         {             for (j=row_max;j>=row_min;j--)             {                 dada[j][i+1-j] = count++;             }         }     }     for (i=1;i<=n;i++)     {         for (j=1;j<=n;j++)         {             printf("%5d",dada[i][j]);         }         printf("\n\n");     } }

user: user-3
content: 引用 2 楼 brookmill 的回复:这个思路就是直接把人画这个矩阵的思路用代码写出来了，所以不难理解。关键在于看懂这一句： dada[j][k] = count++; 这说明，不管怎么循环，给数组赋值的次序是按照自然数递增顺序的，从1、2、3直到100。所以，对这个矩阵的遍历赋值，必然是按照对角线左下、右上、左下、右上这样循环依次进行的。 不过楼主的代码和楼主贴出来的运行结果好像不太一样，方向正好相反。 以下注释以n=10为例     for(i=1;i<=2*n-1;i++)    { // 一共19条对角线，第一条是1，第二条是2和3，第三条是4、5、6，……第18条是98和99，第19条是100         if ((i+flag)%2)// 这个控制前进的方向，奇数对角线是从右上到左下，偶数对角线从左下到右上。这个flag其实没用，可以删掉。         { // 这是从右上到左下，也就是1， 4、5、6， 11、12、13、14、15， ……             for (j=1;j<=n;j++)// 从上到下遍历矩阵的每一行             {                 for (k=1;k<=n;k++)// 从左到右遍历本行的每一列。这个循环反过来写也可以，因为每行最多只有一个符合条件的位置                 {// 这个双重循环，遍历了整个矩阵的100个位置，效率有点低                     if (j+k == i+1)// 如果该位置刚好处在现在处理的对角线上，就给赋值                     { // 比如，第三条对角线，i=3，也就是4、5、6，条件是j+k==4，满足条件的是dada[1][3]、dada[2][2]、dada[3][1]                         dada[j][k] = count++; ...         else         { // 这是从左下到右上，也就是2、3， 7、8、9、10， ……             for (j=n;j>=1;j--)// 从下到下上遍历矩阵的每一行             {                 for (k=n;k>=1;k--)// 从右到左遍历本行的每一列。这个循环反过来写也可以，因为每行最多只有一个符合条件的位置

user: user-2
content: 这个思路就是直接把人画这个矩阵的思路用代码写出来了，所以不难理解。关键在于看懂这一句： dada[j][k] = count++; 这说明，不管怎么循环，给数组赋值的次序是按照自然数递增顺序的，从1、2、3直到100。所以，对这个矩阵的遍历赋值，必然是按照对角线左下、右上、左下、右上这样循环依次进行的。 不过楼主的代码和楼主贴出来的运行结果好像不太一样，方向正好相反。 以下注释以n=10为例     for(i=1;i<=2*n-1;i++)    { // 一共19条对角线，第一条是1，第二条是2和3，第三条是4、5、6，……第18条是98和99，第19条是100         if ((i+flag)%2)// 这个控制前进的方向，奇数对角线是从右上到左下，偶数对角线从左下到右上。这个flag其实没用，可以删掉。         { // 这是从右上到左下，也就是1， 4、5、6， 11、12、13、14、15， ……             for (j=1;j<=n;j++)// 从上到下遍历矩阵的每一行             {                 for (k=1;k<=n;k++)// 从左到右遍历本行的每一列。这个循环反过来写也可以，因为每行最多只有一个符合条件的位置                 {// 这个双重循环，遍历了整个矩阵的100个位置，效率有点低                     if (j+k == i+1)// 如果该位置刚好处在现在处理的对角线上，就给赋值                     { // 比如，第三条对角线，i=3，也就是4、5、6，条件是j+k==4，满足条件的是dada[1][3]、dada[2][2]、dada[3][1]                         dada[j][k] = count++; ...         else         { // 这是从左下到右上，也就是2、3， 7、8、9、10， ……             for (j=n;j>=1;j--)// 从下到下上遍历矩阵的每一行             {                 for (k=n;k>=1;k--)// 从右到左遍历本行的每一列。这个循环反过来写也可以，因为每行最多只有一个符合条件的位置

user: user-4
content: 这段代码是干什么的？