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;
}