zigzag数组,螺旋数组生成

转自http://www.cnblogs.com/lovell-liu/archive/2011/09/19/2181598.html

zigzag数组

复制代码
#include "stdio.h"
#include
"stdlib.h"

int GetNum(int i,int j, int N, constint* sum);
void SUM(int N, int* sum);

/*
打印zigzag数组
0 1 5 6 14 15 27 28 44 45 65 66 90
2 4 7 13 16 26 29 43 46 64 67 89 91
3 8 12 17 25 30 42 47 63 68 88 92 113
9 11 18 24 31 41 48 62 69 87 93 112 114
10 19 23 32 40 49 61 70 86 94 111 115 132
20 22 33 39 50 60 71 85 95 110 116 131 133
21 34 38 51 59 72 84 96 109 117 130 134 147
35 37 52 58 73 83 97 108 118 129 135 146 148
36 53 57 74 82 98 107 119 128 136 145 149 158
54 56 75 81 99 106 120 127 137 144 150 157 159
55 76 80 100 105 121 126 138 143 151 156 160 165
77 79 101 104 122 125 139 142 152 155 161 164 166
78 102 103 123 124 140 141 153 154 162 163 167 168
*/
int main()
{
int N;
scanf(
"%d", &N);
int**a = (int**)malloc(N*sizeof(int));
for(int i=0; i < N; i++)
{
a[i]
= (int*) malloc(N*sizeof(int));
}
int*sum = (int*)malloc((2*N-1)*sizeof(int));
SUM(N, sum);
for(int i=0; i<N; i++)
{
for(int j=0; j<N; j++)
{
a[i][j]
= GetNum(i, j, N, sum);
}
}

for(int i=0; i<N; i++)
{
for(int j=0; j<N; j++)
{
printf(
"%4d", a[i][j]);
}
printf(
"\n");
}
system(
"pause");
}

int GetNum(int i,int j, int N, constint* sum)
{
int lev=i+j;
if((i+j)<N)
{
if((i+j)%2==0)
{
return sum[i+j] - i;
}
else
{
return sum[i+j]-j;
}
}
else
{
if((i+j)%2==0)
{
return sum[i+j] -(N-1-j);
}
else
{
return sum[i+j]-(N-1-i);
}
}
}

void SUM(int N, int* sum)
{
sum[
0]=0;
for(int i=1; i<=2*N-1; i++)
{
if(i<N)
{
sum[i]
= sum[i-1]+i+1;
}
else
{
sum[i]
= sum[i-1]+2*N-i-1;
}
}
}
复制代码

螺旋数组

复制代码
/*
打印螺旋数组
111 112 113 114 115 116 117 118 119 120 121
110 73 74 75 76 77 78 79 80 81 82
109 72 43 44 45 46 47 48 49 50 83
108 71 42 21 22 23 24 25 26 51 84
107 70 41 20 7 8 9 10 27 52 85
106 69 40 19 6 1 2 11 28 53 86
105 68 39 18 5 4 3 12 29 54 87
104 67 38 17 16 15 14 13 30 55 88
103 66 37 36 35 34 33 32 31 56 89
102 65 64 63 62 61 60 59 58 57 90
101 100 99 98 97 96 95 94 93 92 91
*/
#include
<stdio.h>
#include
<stdlib.h>
#include
<math.h>

#define MAX(X,Y) (X)>=(Y)?(X):(Y);
int foo(int ,int);


int main()
{
int n;
scanf(
"%d", &n);
for(int j=n; j>=-1*n; j--)
{
for(int i=-1*n; i<=n;i++)
{
printf(
"%4d", foo(i, j));
}
printf(
"\n");
}
system(
"pause");
}

int foo(int x,int y)
{
int l=MAX(abs(x), abs(y));
int max=(2*l-1)*(2*l-1);
if(x==y && x==0)
{
return1;
}
if(x==y && x==l)
{
return max+8*(l);
}
if(x==l)
{
return max +(l-y);
}
elseif(y==-1*l)
{
return max +2*l+(l-x);
}
elseif(x==-1*l)
{
return max +6*l -(l-y);
}
else
{
return max+8*(l) - (l-x);
}
}



问题描述:螺旋式打印一个二维数组。如

1     16     3     2     17

8     6       4     3     23  

2     5       7     8     12

21   2       4     6     13

要求打印后顺序为:

1     16   3     2     17   23     12     13   6     4     2     21     2     8   6     4     3     8     7     5

 

 

        此题的思路有很多中,最容易想到的方法就是设置一个表示方向的变量,根据当前的方向来判断下一步的操作,当到达边界的时候方向顺时针改变。另外有一个bool型的数组来表示相应位置是否被访问过,初始化都是0(未访问),当输出一个数就把相应位置的标记置为1。在前方向上如果碰到已经被访问过的位置就顺时针改变方向,一直到最后所有位置的数都访问位置。

 

 

        个人觉得上面的算法写出的程序比较繁琐,下面提供一种比较简单的算法。在输出的时候可以给水平方向和垂直方向各设置两个坐标,start_x, end_x, start_y, end_y, 分别表示当前水平方向输出区间应该在start_x和end_x之间,垂直方向输出区间在start_y和end_y直接,每次转弯的时候只需要改变区间的边界就可以了。具体代码如下:

 

  1. int     arr[6][5]= 
  2. {{1,           16,           3,           2,             17}, 
  3. {8,           6,             4,           3,             23}, 
  4. {2,           5,             7,           8,             12}, 
  5. {21,         2,             4,           6,             13}, 
  6. {11,       111,           111,       132,         12}, 
  7. {31,       311,           4111,     332,         32} 
  8. };      
  9. void main()
  10. {
  11.         // 初始的区间坐标
  12.     int startX = 0, endX = 4;
  13.     int startY = 0, endY = 5;
  14.     
  15.     while(startX<=endX && startY<=endY)  // 循环条件
  16.     {
  17.         int i;
  18.         for(i=startX; i<=endX; i++)  // 输出上边的行
  19.             cout << arr[startY][i] << " ";
  20.         startY ++;         // 行的开始坐标增加
  21.         for(i=startY; i<=endY; i++)  // 输出右边的列
  22.             cout << arr[i][endX] << " ";
  23.         endX --;           // 列的结束坐标减小
  24.         for(i=endX; i>=startX; i--)   // 输出下边边的行
  25.             cout << arr[endY][i] << " ";
  26.         endY --;           // 行的结束坐标减小
  27.         for(i=endY; i>=startY; i--)  // 输出左边的列
  28.             cout << arr[i][startX] << " ";
  29.         startX ++;         // 列的开始坐标增加
  30.     }
  31. }
 
posted @ 2012-10-11 22:13  liangflying  阅读(869)  评论(0编辑  收藏  举报