题目
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 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
思路
打印螺旋数组,首先确定m、n的值,n就是<=sqrt(N)的最大因子(这里如果从1
开始遍历找n就会有测试点超时)。如果先找m,也就是>=sqrt(N)的最大因子,就会麻烦一点,因为sqrt(N)取整后,m可能会取到错误的值,如 N = 12时,m会取到3。
接下来就是画螺旋了,这种题目一般就是“一圈一圈”的画,不断更新边界位置即可。
代码
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
int main() {
int l, m, n;
scanf("%d", &l);
vector<int> a(l);
for (int i=0; i<l; i++){
scanf("%d", &a[i]);
}
sort(a.begin(), a.end());
for (n=sqrt(l); n>=1; n--){
if (l % n == 0){
m = l / n;
break;
}
}
vector<vector<int> > b(m, vector<int>(n));
int pos = l - 1;
int mm = m; //i结束位置
int nn = n; //j结束位置
int i = 0;
int j = 0;
while (pos >= 0){
//i、j起始位置
int si = i;
int sj = j;
while (j<nn){
b[i][j++] = a[pos--];
}
i++;
j--;
if (pos<0) break;
while (i<mm){
b[i++][j] = a[pos--];
}
if (pos<0) break;
i--;
j--;
while (j>=sj){
b[i][j--] = a[pos--];
}
if (pos<0) break;
i--;
j++;
while (i>si){
b[i--][j] = a[pos--];
}
i++;
j++;
mm--;
nn--;
}
for (i=0; i<m; i++){
printf("%d", b[i][0]);
for (j=1; j<n; j++){
printf(" %d", b[i][j]);
}
printf("\n");
}
return 0;
}