形成一个zigzag数组(JPEG编码里取像素数据的排列顺序)

面试例题:输入n,求一个nXn矩阵,规定矩阵沿45度递增,形成一个zigzag数组(JPEG编码里取像素数据的排列顺序),请问如何用C++实现?

(中国台湾著名硬件公司2007年11月面试题)(自程序员面试宝典第二版p89)

程序实现如下:

分析:例如输入为8的时候得到的zigzag数组为:

形成一个zigzag数组(JPEG编码里取像素数据的排列顺序) - 马门dd - 希望每个人都过的很好,都能幸福生活!
 从上面的标记的方向应该可以看到,这个数组就是按照对角规律进行的,那么我在写程序的时候,会用一个两层的for来填充这个数组。为了从这个规律入手,我们在考虑这个数据的填充是要理清一个思路,不要按那两层的for循环考虑,只需要考虑第(i,j)位置与(i,j)的关系就OK了,那么对应的填充函数就填充相应的(i,j)的函数。
 
由于对同一斜线上的元素,s=i+j为常数

1.对于第n个(n<N)斜线:

每一斜线个数比上一行多一个,则每一斜线的第一个值表示了在该斜线之前元素的个数,即一个累加 :

(s+1)*s/2

斜线中的任意元素可表示为s*(s+1)/2+i

2.同理对于第n个(n>=N)的斜线:

每斜线的元素个数开始减少,等差数组不适用,为方便起见,可以用减法计算元素个数,

剩余元素的斜线数目:s1=(2(N-1)-(i+j))

元素值=(N*N-(s1+1)*s1/2)-(N-i)=下一斜线的第一个元素值-该斜线剩余元素的个数
 
程序如下:
#include <iostream>
#include <stdio.h>
using namespace std;

int main()
{
	int N;
	int s, i, j;
	int squa;
	scanf("%d", &N);
	int **a = (int **)malloc(N * sizeof(int));
	if(NULL == a)
	{
		return 0;
	}
	//空间分配
	for(i = 0; i < N; i++)
	{
		if(NULL == (a[i] = (int*)malloc(N * sizeof(int))))
		{
			while(--i >= 0)
			{
				free(a[i]);
			}
			free(a);
			return 1;
		}
	}
	squa = N * N;
	//求对应位置上应填写的值
	for(i = 0; i < N; i++)
	{
		for(j = 0; j < N; j++)
		{ 
			s = i + j;
			
			if(s < N)//上三角
			{
				s = i + j;//为了看的更清楚,这里加了这条与下面对称的语句    
				a[i][j] = s * (s + 1) / 2 + ((0 == (i + j) % 2) ? i : j);
			}
			else//下三角
			{
				s = (N - 1 - i) + (N - 1 - j);
				a[i][j] = squa - s * (s + 1) / 2 - (N - ((0 == (i + j) % 2) ? i : j));
			}
		}
	}
	//打印输出
	for(i = 0; i < N; i ++)
	{
		for(j = 0; j < N; j++)
		{
			printf("%6d", a[i][j]);
		}
		printf("\n");
	}
	
	return 0;
}

  

posted @ 2013-08-18 17:04  凡程子  阅读(2866)  评论(0编辑  收藏  举报
View Code