/**
* 描述:打印zigzag矩阵
* 0 1 5 6 14 15 27 28
* 2 4 7 13 16 26 29 42
* 3 8 12 17 25 30 41 43
* 9 11 18 24 31 40 44 53
* 10 19 23 32 39 45 52 54
* 20 22 33 38 46 51 55 60
* 21 34 37 47 50 56 59 61
* 35 36 48 49 57 58 62 63
*
* Date: 2011-08-08
*/
# include <iostream >
# include <iomanip >
using namespace std;
int a[ 10][ 10];
void PrintZigzag( int n)
{
int value = 0;
int i,j,k;
int num;
//上三角
for (i = 0; i <n; i ++)
{
num = 0;
if ( 0 == i % 2)
{ /*偶数*/
j = i;
k = 0;
while (num ++ < = i)
{
a[j --][k ++] = value ++;
}
}
else
{ /*奇数*/
j = 0;
k = i;
while (num ++ < = i)
{
a[j ++][k --] = value ++;
}
}
}
//下三角
for (i = n - 2; i > = 0; i --)
{
num = 0;
if ( 0 == i % 2)
{ /*偶数*/
j = n - 1;
k = n - 1 - i;
while (num ++ < = i)
{
a[j --][k ++] = value ++;
}
}
else
{ /*奇数*/
j = n - 1 - i;
k = n - 1;
while (num ++ < = i)
{
a[j ++][k --] = value ++;
}
}
}
}
/**
* test
*/
int main()
{
int n, i, j;
cin >> n;
for(i = 0; i < n; i ++)
{
for (j = 0; j < n; j ++)
{
a[i][j] = 0;
}
}
PrintZigzag(n);
for(i = 0; i < n; i ++)
{
for (j = 0; j < n; j ++)
{
cout << setw( 4) << a[i][j];
}
cout << endl;
}
return 1;
}
* 描述:打印zigzag矩阵
* 0 1 5 6 14 15 27 28
* 2 4 7 13 16 26 29 42
* 3 8 12 17 25 30 41 43
* 9 11 18 24 31 40 44 53
* 10 19 23 32 39 45 52 54
* 20 22 33 38 46 51 55 60
* 21 34 37 47 50 56 59 61
* 35 36 48 49 57 58 62 63
*
* Date: 2011-08-08
*/
# include <iostream >
# include <iomanip >
using namespace std;
int a[ 10][ 10];
void PrintZigzag( int n)
{
int value = 0;
int i,j,k;
int num;
//上三角
for (i = 0; i <n; i ++)
{
num = 0;
if ( 0 == i % 2)
{ /*偶数*/
j = i;
k = 0;
while (num ++ < = i)
{
a[j --][k ++] = value ++;
}
}
else
{ /*奇数*/
j = 0;
k = i;
while (num ++ < = i)
{
a[j ++][k --] = value ++;
}
}
}
//下三角
for (i = n - 2; i > = 0; i --)
{
num = 0;
if ( 0 == i % 2)
{ /*偶数*/
j = n - 1;
k = n - 1 - i;
while (num ++ < = i)
{
a[j --][k ++] = value ++;
}
}
else
{ /*奇数*/
j = n - 1 - i;
k = n - 1;
while (num ++ < = i)
{
a[j ++][k --] = value ++;
}
}
}
}
/**
* test
*/
int main()
{
int n, i, j;
cin >> n;
for(i = 0; i < n; i ++)
{
for (j = 0; j < n; j ++)
{
a[i][j] = 0;
}
}
PrintZigzag(n);
for(i = 0; i < n; i ++)
{
for (j = 0; j < n; j ++)
{
cout << setw( 4) << a[i][j];
}
cout << endl;
}
return 1;
}
方法虽蠢却易理解。
通过观察zigzag矩阵可发现几个特点:
- 左上三角(以对角线方向查看)个数从1递增至n(矩阵维数),右下三角从n-1递减至1。则可以将zigzag矩阵分为上三角和下三角两部分处理。
- 观察zigzag矩阵,以对角线方向计(行数从0开始计数),则偶数行规律是:从左到右;奇数行规律是:从右到左。则再分为奇偶行进行处理。
当然,有一种十分巧妙的方法如下。
#
include
<stdio.h
>
# include <stdlib.h >
int main()
{
int N;
int s, i, j;
int squa;
scanf( "%d", &N);
/* 分配空间 */
int * *a = ( int * *)malloc(N * sizeof( int *));
if(a == NULL)
return 0;
for(i = 0; i < N; i ++)
{
if((a[i] = ( int *)malloc(N * sizeof( int))) == NULL)
{
while( --i > = 0)
free(a[i]);
free(a);
return 0;
}
}
/* 数组赋值 */
squa = N *N;
for(i = 0; i < N; i ++)
for(j = 0; j < N; j ++)
{
s = i + j;
if(s < N) /*上三角*/
{
a[i][j] = s*(s+1)/2 + (((i+j)%2 == 0)? j : i);
}
else
{ /*下三角*/
s = (N-1-i) + (N-1-j);
a[i][j] = squa - s*(s+1)/2 - (N - (((i+j)%2 == 0)? j : i));
}
}
/* 打印输出 */
for(i = 0; i < N; i ++)
{
for(j = 0; j < N; j ++)
{
printf( "%6d", a[i][j]);
}
printf( "\n");
}
return 1;
}
# include <stdlib.h >
int main()
{
int N;
int s, i, j;
int squa;
scanf( "%d", &N);
/* 分配空间 */
int * *a = ( int * *)malloc(N * sizeof( int *));
if(a == NULL)
return 0;
for(i = 0; i < N; i ++)
{
if((a[i] = ( int *)malloc(N * sizeof( int))) == NULL)
{
while( --i > = 0)
free(a[i]);
free(a);
return 0;
}
}
/* 数组赋值 */
squa = N *N;
for(i = 0; i < N; i ++)
for(j = 0; j < N; j ++)
{
s = i + j;
if(s < N) /*上三角*/
{
a[i][j] = s*(s+1)/2 + (((i+j)%2 == 0)? j : i);
}
else
{ /*下三角*/
s = (N-1-i) + (N-1-j);
a[i][j] = squa - s*(s+1)/2 - (N - (((i+j)%2 == 0)? j : i));
}
}
/* 打印输出 */
for(i = 0; i < N; i ++)
{
for(j = 0; j < N; j ++)
{
printf( "%6d", a[i][j]);
}
printf( "\n");
}
return 1;
}
通过观察zigzag数组,可以发现,对角线上(i+j)为常数,记为s(s=i+j)。(i为行数,j为列数)
仍然是分为上三角和下三角两部分处理。
对于上三角,每一个斜线上的个数比上一行多一个。且,每个斜线上的第一个元素表示了该斜线之前元素的个数。运用等差数列求和公式,则每一斜线第一个元素的值为 (1 + (i+j)) * (i+j) / 2 = (1 + s) * s / 2
斜线中的任意元素可表示为s*(s+1)/2+i(此处来个奇偶判断就知道是加i还是加j了。)那么就不难理解代码中 a[i][j] = s*(s+1)/2 + (((i+j)%2 == 0)? j : i);的含义了。
对于下三角,斜线上元素的个数是递减的。反过来看可以看成是递增的,就仍然可以套用等差数列求和公式,求出剩下的元素的个数,用总元素个数减去剩下的元素个数就是当前斜线上的第一个元素值。
我们知道所有元素的个数是n*n,则该斜线的第一个元素值为n*n - s*(s+1)/2。此处的s就不是i+j了,而是(n-1-i)+(n-1-j)。这样也不难理解代码中s = (N-1-i) + (N-1-j); a[i][j] = squa - s*(s+1)/2 - (N - (((i+j)%2 == 0)? j : i));两句的含义了。
转自:http://blog.163.com/yangjun1988422@126/blog/static/4741291720117842634276/