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、要求矩阵的规模为 m 行 n 列,满足条件:m×n 等于 N;m≥n;且 m−n 取所有可能值中的最小值。
容易看出m、n位于√N两边(m>=n,m位于√N右边,n位于√N左边,或m=n=√N);要使得m-n的值最小,可以想到找到
i∈[√N,N]内第一个满足N%i=0。
scanf("%d",&N);
for(int i=ceil(sqrt(1.0*N));i<=N;i++){
if(N%i==0){
n2=i;
break;
}
}
n1=N/n2;
2、从左上角第 1 个格子开始,按顺时针螺旋方向填充矩阵。
我这里借用了DFS的思想,做了一些改变。顶点的值x、y为要填充的二维矩阵,每次从四个方向(按右、下、左、上顺序)一
一直走到底。
void DFS(int i,int j){
for(int k=0;k<4;k++){
int newX=i+X[k];
int newY=j+Y[k];
if(iscan(newX,newY)&&!hashTable[newX][newY]){
//k:0 右 1 下 2 左 3 上 沿着一个方向一路走直到走到边界或者已被访问的顶点。
while(iscan(newX,newY)&&!hashTable[newX][newY]){
hashTable[newX][newY]=true;//记录已经访问
res[newX][newY]=vt[_index++];//写入二维矩阵
newX+=X[k];
newY+=Y[k];
}
newX-=X[k];//复位X
newY-=Y[k];//复位Y
DFS(newX,newY);
}
}
}
AC代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <string>
#include <math.h>
using namespace std;
int N,x,n1,n2;
int X[4]={0,1,0,-1};
int Y[4]={1,0,-1,0};
vector<int> vt;
vector<vector<bool> > hashTable;
vector<vector<int> >res;
bool iscan(int i,int j){
bool flag=true;
if(i<0||j<0||i>=n2||j>=n1)
flag=false;
return flag;
}
bool cmp(int a,int b){
return a>b;
}
void show(){
for(int i=0;i<n2;i++){
for(int j=0;j<n1;j++){
printf("%d",res[i][j]);
if(j!=n1-1)
printf(" ");
}
printf("\n");
}
}
int index=0;
void DFS(int i,int j){
for(int k=0;k<4;k++){
int newX=i+X[k];
int newY=j+Y[k];
if(iscan(newX,newY)&&!hashTable[newX][newY]){
while(iscan(newX,newY)&&!hashTable[newX][newY]){
hashTable[newX][newY]=true;
res[newX][newY]=vt[index++];
newX+=X[k];
newY+=Y[k];
}
newX-=X[k];
newY-=Y[k];
DFS(newX,newY);
}
}
}
int main(){
scanf("%d",&N);
for(int i=ceil(sqrt(1.0*N));i<=N;i++){
if(N%i==0){
n2=i;
break;
}
}
n1=N/n2;
for(int i=0;i<N;i++){
scanf("%d",&x);
vt.push_back(x);
}
sort(vt.begin(),vt.end(),cmp);
for(int i=0;i<n2;i++){
vector<bool> temp1;
vector<int> temp2;
for(int j=0;j<n1;j++){
temp1.push_back(false);
temp2.push_back(0);
}
hashTable.push_back(temp1);
res.push_back(temp2);
}
DFS(0,-1);
show();
return 0;
}