1050 螺旋矩阵 (25 分)

143 阅读1分钟

1050 螺旋矩阵 (25 分)

题目链接

算法分析

关键就是以下几点:
(1)排序:sort
(2)矩阵的行数和列数的求法:从根号n向下取整开始遍历,直到整除。
(3)螺旋填充:这个是比较麻烦的,第一,用cnt记录当前已经填充的数的数目,并用while循环控制,第二,临界判断,一个是是否超出矩阵,一个是是否已经填过,都需要判断出来。第三,方向数组的使用,用dir的值来判断需要填充的下一个值的位置。

代码实现

#include<bits/stdc++.h>
using namespace std;
#define N 10005
#define M 105
int a[N];
int mp[M][M];
int x[4] = {1, 0, -1, 0};//方向数组
int y[4] = {0, 1, 0, -1};//方向数组
int dir;
bool cmp(int a, int b){//排序函数
	return a > b;
}
int p, q;//x和 y的范围
int on[N][N];//是否已经被用过
int main(){
	int n;
	scanf("%d", &n);
	for(int i = 1; i <= n; ++ i)
		scanf("%d", a + i);
	sort(a + 1, a + n + 1, cmp);
	for(int i = (int)sqrt(n); i >= 1; -- i)
		if(n % i == 0){
			p = i;
			q = n / i;
			break;
		}
	for(int j = 1; j <= q; ++ j)
		for(int i = 1; i <= p; ++ i)
			on[i][j] = 1;
	int cnt = 1;
	int x_now = 1, y_now = 1;
	on[x_now][y_now] = 0;//关键的初始化,标记第一个点为已到达过
	mp[x_now][y_now] = a[cnt];
	while(cnt < n){
		++ cnt;
		if(x_now + x[dir] >= 1 && x_now + x[dir] <= p && y_now + y[dir] >= 1 && y_now + y[dir] <= q
			&& on[x_now + x[dir]][y_now + y[dir]]){
				mp[x_now + x[dir]][y_now + y[dir]] = a[cnt];
				on[x_now + x[dir]][y_now + y[dir]] = 0;
			}
		else{
			++ dir;
			dir %= 4;
			mp[x_now + x[dir]][y_now + y[dir]] = a[cnt];
			on[x_now + x[dir]][y_now + y[dir]] = 0;
		}
		x_now += x[dir];
		y_now += y[dir];
	}
	for(int j = 1; j <= q; ++ j)//不要搞反p和q
		for(int i = 1; i <= p; ++ i){
			printf("%d", mp[i][j]);
			if(i < p) printf(" ");
			else	printf("\n");	
		}
	return 0;
}