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
乙级中稍稍有点水平的题目
我的做法: 既然是在矩阵内走一遍,立刻想到了BFS走迷宫,遇到不能走的回溯后换个方向继续走。
假设初始在(0,-1) 不就是先往右-》往下-》往左-》往上 依次循环直到值赋完
变换方向的依据:
a、已经走过了(已经赋过值了,判断是否是初始值即可)
b、外层走的时候,数组下标越界了 判断行标r是否在[0,m-1]内,列标c是否在[0,n-1]内即可(-1、m、n时越界)然后就没有难度了^_^
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+10;
int a[maxn];
int mat[maxn][maxn]={0};//能开这么大 就这么大吧 9998=4999*2 可能还有比4999更大的质数 二维数组也可以初始化为0
int dx[]={0,1, 0,-1};//螺旋方向 右-》下-》左-》上
int dy[]={1,0,-1,0};
int main(){
// freopen("in.txt","r",stdin);
int N,m,n;
cin>>N;
for(m=ceil(sqrt(N));N%m!=0;m++);n=N/m;//确定m,n
for(int i=0;i<N;i++) scanf("%d",a+i);
sort(a,a+N);
int r=0,c=-1,d=0;//r行 c列 d方向 初始位置确实在(0,-1)
while(N--){//赋值n次 N-1~0
r+=dx[d];c+=dy[d];//先尝试原来方向走一步
if(mat[r][c]!=0||r==m||c==n||r==-1||c==-1) {//此步不能走 碰壁走墙里去了
r-=dx[d];c-=dy[d];N++;//原路退回上一步位置
d=(d+1)%4;//换方向
continue;//本次不走了
}
mat[r][c]=a[N];//否则正常走 正常赋值
}
for(int i=0;i<m;i++)
for(int j=0;j<n;j++){
cout<<mat[i][j];
if(j==n-1) cout<<endl;
else cout<<" ";
}
return 0;
}