题目描述
This time your job is to fill a sequence of N positive integers into a spiral matrix in non-increasing order. A spiral matrix is filled in from the first element at the upper-left corner, then move in a clockwise spiral. The matrix has m rows and n columns, where m and n satisfy the following: m×n must be equal to N; m≥n; and m−n is the minimum of all the possible values.
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N. Then the next line contains N positive integers to be filled into the spiral matrix. All the numbers are no more than
1
0
4
10^4
104. The numbers in a line are separated by spaces.
Output Specification:
For each test case, output the resulting matrix in m lines, each contains n numbers. There must be exactly 1 space between two adjacent numbers, and no extra space at the end of each line.
Sample Input:
12
37 76 20 98 76 42 53 95 60 81 58 93
Sample Output:
98 95 93
42 37 81
53 20 76
58 60 76
解题思路
1.计算行列数,
r
o
w
∗
c
o
l
=
N
,
r
o
w
>
=
c
o
l
且
差
值
最
小
row*col = N ,row >= col 且差值最小
row∗col=N,row>=col且差值最小;
就是对N求差值最小的因数分解
2.排序;
sort解决,默认是升序,填入数字时从后往前
3.控制数字填入位置;
右->下->左->上->右->下…,用常量数组控制方向,简化代码
代码
#include <iostream>
#include <cstring>
#include <fstream>
#include <algorithm>
#include <cmath>
using namespace std;
#define DEBUG
#ifdef DEBUG
#define cin ifile
ifstream ifile("input.txt");
#endif
const int MAXN = 100000+10;
const int dir[8] = {
0,1 //right
,1,0 //down
,0,-1 //left
,-1,0 //up
};
int main(){
int N;
cin>>N;
int nums[MAXN] = {0};
int res[101][101]={0};
for(int i=0;i<N;++i){
cin>>nums[i];
}
//calculate width and height
int w=sqrt(N),h = 1;
while(N%w != 0){
w--;
}
h = N / w;
//sort as ascend
sort(nums,nums+N);
int tm=0,tn = 0, m = 0,n = 0,base = 0 ;
for(int i=0;i<N;++i){
res[m][n] = nums[N-i-1];
//last number needn't to calculate next position
if(i == N-1){
break;
}
//calculate next potential postion
tm += dir[2*base];
tn += dir[2*base+1];
//change direction when potential position is out of range or has been filled
while(tm < 0 || tm >= h || tn < 0 || tn >= w || res[tm][tn] > 0){
tm = m;
tn = n;
base = (base+1)%4;
tm += dir[2*base];
tn += dir[2*base+1];
}
m = tm;
n = tn;
}
for(int i=0;i<h;i++){
for(int j=0;j<w;++j){
if(j != 0){
cout<<' ';
}
cout<<res[i][j];
}
if(i != h-1){
cout<<endl;
}
}
return 0;
}