蛇形数组

蛇形数组


题目要求

给定一个整形数N,要求形成一个N * N的矩阵。矩阵中的每一项存放的数从1到N * N,以蛇形迂回的顺序存放。最后按行按列依次输出数组中的元素。

例如 3 * 3 的数组存放情况如下:
1 2 3
8 9 4
7 6 5

例如 5 * 5数组存放情况如下:
1 2 3 4 5
16 17 18 19 6
15 24 25 20 7
14 23 22 21 8
13 12 11 10 9

样例输入:3

输出:1 2 3 8 9 4 7 6 5(每一位数之间有一空格)

样例输入:5

输出:1 2 3 4 5 16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 12 11 10 9(每一位数之间有一空格)

解题思路

虽然说题目是要求生成一个二位数组,其实也可以用一个一维数组来存储,通过计算,把二位数组的下标转换成一维数组的下标。比如一个4 * 4的数组,第2行第3列的行数本来用二维数组存储的位置是 int[1][2],换算成一维数组则是 int[2 * 4 + 3 - 1],即 int[10]的位置。

具体在存放数的时候,是模拟蛇形迂回的路线存放的,从1~N * N的顺序填满数组。可以把存数的动作分解成一轮轮,每一轮把一个数组最外圈的位置填满,然后递归填满向里面的一圈。比如对于一个 6 * 6 的数组A,第一轮把最外圈上→右→下→左的边共20个位置依次用1~20顺序填满。这样完成第一轮后,剩下未填满的是一个4 * 4的数组,记作数组B。接下来用21~32共12个数依次把数组B上右下左的边一次填满。这样每次递归完成存数。注意设立递归基,以及考虑原始数组边长度奇偶性对最后一次递归的影响。

代码实现

#include<iostream>
using namespace std;

void createSnakeArr(int startNum, int currx, int curry, int a[], int currSize, int totalSize) {
	int n = startNum;	// startNum 为新开始一轮存放的第一个数
	int x = currx;		// currx 为当前一轮存放第一个数的行数
	int y = curry;		// curry 为当前一轮存放第一个数的列数
	if (currSize < 1) return;	// 递归基, currSize为当前这一轮数组的大小
	if (currSize == 1) {		// 处理 N * N 数组(N为奇数时最后一轮时最后一个数的存放)  
		a[x * totalSize + y] = n;
		cout << n << ": " << x << " " << y << endl;
		return;
	}
	while (n < startNum + 4 * currSize - 4) {
		if (x == currx && y < curry + currSize - 1) {
			// 填满上方一行 
			a[x * totalSize + y] = n;
			y++;
			n++;
		}
		if (y == curry + currSize - 1 && x < currx + currSize - 1) {
			// 填满右边一列
			a[x * totalSize + y] = n;
			x++;
			n++;
		}
		if (x == currx + currSize - 1 && y > curry) {
			// 填满下方一行
			a[x * totalSize + y] = n;
			y--;
			n++;
		}
		if (y == curry && x > currx) {
			// 填满左边一列
			a[x * totalSize + y] = n;
			x--;
			n++;
		}
	}
	// 递归生成小一圈的数组
	createSnakeArr(a[(currx + 1) * totalSize + curry] + 1, currx + 1, curry + 1, a, currSize - 2, totalSize);
} 

	void printArray(int *a, int length) {
	cout << a[0];
	for (int i = 1; i < length; i++) {
		cout << " " << a[i];
	}
	cout << endl;	
}

int main() {
	int N;
	cin >> N;
	int n = N * N;
	int *snakeArr = new int[n];
	createSnakeArr(1, 0, 0, snakeArr, N, N);
	printArray(snakeArr, n);
	delete []snakeArr;
	return 0;
}
posted @ 2016-04-04 20:59  黑巧书生  阅读(1488)  评论(0编辑  收藏  举报