PAT : 1050. 螺旋矩阵(25)

本题要求将给定的N个正整数按非递增的顺序,填入“螺旋矩阵”。所谓“螺旋矩阵”,是指从左上角第1个格子开始,按顺时针螺旋方向填充。要求矩阵的规模为m行n列,满足条件:m*n等于N;m>=n;且m-n取所有可能值中的最小值。

输入格式:

输入在第1行中给出一个正整数N,第2行给出N个待填充的正整数。所有数字不超过104,相邻数字以空格分隔。

输出格式:

输出螺旋矩阵。每行n个数字,共m行。相邻数字以1个空格分隔,行末不得有多余空格。

输入样例:
12
37 76 20 98 76 42 53 95 60 81 58 93
输出样例:
98 95 93
42 37 81
53 20 76
58 60 76

俗话说得好,大问题很复杂,拆解成若干个小问题就好了,这个问题里就可以拆出几个小问题:1)获得一个数最相近的两个因子;2)排序;3)排出螺旋矩阵。就这三个,第一个问题不要去枚举,要知道这两个最相近的因子是一定在这个数的平方根的两侧的,或者就是平方根,所以求出平方根,在平方根及平方根的附近找就能很快找到,除了一些数值较大的质数比较慢一些,第二个问题直接用qsort,第三问其实也没太大难度,我就是按照右下左上这四个方向不断往里填数就解决了,具体看代码

这里要详细说一下二维数组的大小,之前我想最多10000个数,a[100][100]就够了嘛,后面看到段错误才意识到不对,9999个数怎么办9和1111貌似就是最接近的两个因子了,更不要说更大的一些质数,行可能会有10000行左右,如果静态申请数组,可能要a[10000][100],内存浪费太大,所以我是采用malloc动态申请内存


#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int cmp (const void *a, const void *b)
{
	return *((int *)b) - *((int *)a);
}

int closestFactor(int listSize)
{
	int factor = (int) sqrt(listSize);
	while(listSize % factor != 0)
	{
		factor--;
	}
	return factor;
}

int main()
{
	int N, i, j;
	scanf("%d", &N);
	int *num = (int *) malloc (N * sizeof(int));
	for(i = 0; i < N; i++)
	{
		scanf("%d", &num[i]);
	}
	int m, n;
	n = closestFactor(N);
	m = N / n;

	qsort(num, N, sizeof(int), cmp);
	
	int **matrix = (int **)malloc(m * sizeof(int*));
	for(i = 0; i < m; i++)
	{	
		matrix[i] = (int *) malloc (n * sizeof(int));
		for(j = 0; j < n; j++)
		{
			matrix[i][j] = 0;
		}
	}

	int empty = N;
	int position = 0;
	int direction = 0; //0:right, 1:down, 2:left, 3:up
	i=0;j=0;
	for(; empty > 0 && position < N;)
	{
		direction %= 4;
		if(direction == 0)
		{
			for(; j < n && matrix[i][j] == 0; j++)
			{
				matrix[i][j] = num[position++];
				empty--;
			}
			j--;
			i++;
		}
		else if(direction == 1)
		{
			for(; i < m && matrix[i][j] == 0; i++)
			{
				matrix[i][j] = num[position++];
				empty--;
			}
			i--;
			j--;
		}
		else if(direction == 2)
		{
			for(; j >= 0 && matrix[i][j] == 0; j--)
			{
				matrix[i][j] = num[position++];
				empty--;
			}
			j++;
			i--;
		}
		else
		{
			for(; i >= 0 && matrix[i][j] == 0; i--)
			{
				matrix[i][j] = num[position++];
				empty--;
			}
			i++;
			j++;
		}
		direction ++;
	}

	for(i = 0; i < m; i++)
	{
		for(j = 0; j < n; j++)
		{
			if(j > 0)
			{
				printf(" ");
			}
			printf("%d", matrix[i][j]);
		}
		printf("\n");
	}

	return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值